├── compiler ├── avr-gcc-4.8 │ ├── bits │ │ ├── c++0x_warning.h │ │ └── c++config.h │ └── byteswap.h ├── gcc-arm-none-eabi │ ├── byteswap.h │ └── assert.h ├── msp430-elf-gcc │ └── byteswap.h └── xtensa-lx106-elf-gcc │ ├── byteswap.h │ └── assert.h ├── tests ├── esp8266 │ ├── user_config.h │ ├── esp8266_uart.c │ ├── esp8266_user.h │ ├── espcppfix.cpp │ ├── esp8266_init.c │ ├── esp8266.cpp │ ├── esp8266_user.c │ └── eagle.app.v6.mod.ld ├── configuration.h ├── ccs.hpp ├── hosted │ ├── miculog.cpp │ └── main.cpp ├── mega2560 │ └── arduino.cpp ├── msp430 │ ├── msp430.cpp │ ├── msp430_hw.hpp │ ├── hw_memmap.h │ ├── msp430fr.cpp │ └── msp430.hpp ├── photon │ └── gcc.opt ├── miculog.ccs ├── miculog.hpp ├── chaskey.html ├── master.inc ├── test.cpp └── chaskey_test.js ├── changelog.v.1.2.md ├── changelog.v.1.4.md ├── changelog.v.1.1.md ├── changelog.v.1.3.md ├── chaskey.h ├── LICENSE ├── chaskey8s.cpp ├── chaskey.cpp ├── README.md └── chaskey.js /compiler/avr-gcc-4.8/bits/c++0x_warning.h: -------------------------------------------------------------------------------- 1 | /usr/include/c++/4.9/bits/c++0x_warning.h -------------------------------------------------------------------------------- /tests/esp8266/user_config.h: -------------------------------------------------------------------------------- 1 | /* esmp8266 user config. That's the way you do it */ 2 | -------------------------------------------------------------------------------- /compiler/avr-gcc-4.8/byteswap.h: -------------------------------------------------------------------------------- 1 | /* stub for missing byteswap.h */ 2 | #define bswap_32(V) (V) 3 | -------------------------------------------------------------------------------- /compiler/gcc-arm-none-eabi/byteswap.h: -------------------------------------------------------------------------------- 1 | /* stub for missing byteswap.h */ 2 | #define bswap_32(V) (V) 3 | -------------------------------------------------------------------------------- /compiler/msp430-elf-gcc/byteswap.h: -------------------------------------------------------------------------------- 1 | /* stub for missing byteswap.h */ 2 | #define bswap_32(V) (V) 3 | -------------------------------------------------------------------------------- /compiler/xtensa-lx106-elf-gcc/byteswap.h: -------------------------------------------------------------------------------- 1 | /* stub for missing byteswap.h */ 2 | #define bswap_32(V) (V) 3 | -------------------------------------------------------------------------------- /compiler/gcc-arm-none-eabi/assert.h: -------------------------------------------------------------------------------- 1 | /* Suppress assert leading to missing _kill and _getpid_r */ 2 | #define assert(V) 3 | -------------------------------------------------------------------------------- /compiler/xtensa-lx106-elf-gcc/assert.h: -------------------------------------------------------------------------------- 1 | /* Suppress assert leading to missing _kill and _getpid_r */ 2 | #define assert(V) 3 | -------------------------------------------------------------------------------- /tests/esp8266/esp8266_uart.c: -------------------------------------------------------------------------------- 1 | /*this is a dirty trick for adhoc include-based linking of esp8266 uart driver*/ 2 | #include <../driver/uart.c> 3 | -------------------------------------------------------------------------------- /changelog.v.1.2.md: -------------------------------------------------------------------------------- 1 | ## chaskey change log v.1.2 2 | 3 | `ADD` CLOC mode of operation
4 | `FIX` raw() method in block32x4 (`JS`)
5 | `ADD` optional ChaCha benchmarking
6 | -------------------------------------------------------------------------------- /changelog.v.1.4.md: -------------------------------------------------------------------------------- 1 | ## chaskey change log v.1.4 2 | 3 | `MOD` added extra xor(key) and removed unnecessary permute()
4 | `MOD` adjusted tests on MSP430 to fit ROM on MSP430FR6989
5 | -------------------------------------------------------------------------------- /changelog.v.1.1.md: -------------------------------------------------------------------------------- 1 | ## chaskey change log v.1.1 2 | 3 | `FIX` `C++` made derive() constant-time
4 | `FIX` `C++` `JS` init with nonce to use derived key
5 | `FIX` `C++` `JS` apply key with XOR in encrypt decrypt
6 | `FIX` `JS` bug in derive()
7 | `FIX` `JS` bug chaskey_tests/readKey
8 | `FIX` `C++` hexout in hosted/main.cpp
9 | -------------------------------------------------------------------------------- /changelog.v.1.3.md: -------------------------------------------------------------------------------- 1 | ## chaskey change log v.1.3 2 | 3 | `FIX` removed deprecated throw(error) in tests/main.cpp
4 | `FIX` made ror and rol consistent
5 | `FIX` memcmp replaced with time-constant details::equals
6 | `MOD` added extra permute() to improve resistance against related-key attack
7 | `ADD` chaskey::Cipher8s with non-inlined methods to save space
8 | `MOD` adjusted tests on AVR to fit ROM on ATmega256...
9 | -------------------------------------------------------------------------------- /tests/configuration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "miculog.ccs" 3 | struct TestLog; 4 | struct LogAppender { 5 | static void log(miculog::level, const char* fmt, ...) noexcept 6 | __attribute__ ((format (printf, 2, 3))); 7 | }; 8 | namespace miculog { 9 | template struct ClassLogLevels : 10 | Levels {}; 11 | 12 | template 13 | struct appender: public LogAppender {}; 14 | } 15 | -------------------------------------------------------------------------------- /tests/esp8266/esp8266_user.h: -------------------------------------------------------------------------------- 1 | /* 2 | * esp8266_user.h 3 | * 4 | * Created on: Nov 7, 2016 5 | * Author: eugene 6 | */ 7 | #ifndef TOOLS_ESP8266_USER_H_ 8 | #define TOOLS_ESP8266_USER_H_ 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | #include "user_interface.h" 13 | void serial_write(const char*); 14 | void serial_writec(char); 15 | int serial_available(); 16 | char serial_read(); 17 | typedef void (*serial_callback)(unsigned len); 18 | void user_rx_installcb(serial_callback cb); 19 | typedef void (*heartbeat_callback)(int cnt); 20 | void user_hb_installcb(heartbeat_callback cb); 21 | void ets_vprintf(void (*p)(char), const char*, ...); 22 | void ets_putc(char); 23 | unsigned micros(void); 24 | void console_attach(void); 25 | void __libc_init_array(void); 26 | void _init(void); 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* TEST_TOOLS_ESP8266_USER_H_ */ 32 | -------------------------------------------------------------------------------- /chaskey.h: -------------------------------------------------------------------------------- 1 | /* C interface for C++ implementation of Chaskey MAC algorithm 2 | * Very efficient MAC algorithm for microcontrollers 3 | * http://mouha.be/chaskey/ 4 | */ 5 | #include 6 | #pragma once 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /** MAC algorithm */ 11 | void chaskey( 12 | uint8_t *tag, /** destination buffer for the message digest */ 13 | uint32_t taglen, /** length of the destination buffer */ 14 | const uint8_t *m, /** message to process */ 15 | const uint32_t mlen, /** message length */ 16 | const uint32_t k[4], /** encryption key */ 17 | const uint32_t k1[4], /** derived subkey k<<1 */ 18 | const uint32_t k2[4] /** derived subkey k<<2 */ 19 | ); 20 | 21 | /** Key derivation routine */ 22 | void subkeys( 23 | uint32_t k1[4], /** destination for subkey k<<1 */ 24 | uint32_t k2[4], /** destination for subkey k<<2 */ 25 | const uint32_t k[4] /** source key */ 26 | ); 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /tests/esp8266/espcppfix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * avrcppfix.cpp 3 | * Fixes missing dependencies, not implemented in avr-gcc 4 | * and not used by cojson tests 5 | */ 6 | #include 7 | 8 | 9 | typedef int __guard __attribute__((mode (__DI__))); 10 | 11 | extern "C" int __cxa_guard_acquire(__guard *); 12 | extern "C" void __cxa_guard_release (__guard *); 13 | extern "C" void __cxa_guard_abort (__guard *); 14 | extern "C" void __cxa_pure_virtual(void); 15 | int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);} 16 | void __cxa_guard_release (__guard *g) {*(char *)g = 1;} 17 | void __cxa_guard_abort (__guard *) {} 18 | void __cxa_pure_virtual(void) __attribute__((weak)); 19 | void __cxa_pure_virtual(void) {} 20 | 21 | /* this is just a stub, must never be used */ 22 | void * operator new(size_t) __attribute__((weak)); 23 | void * operator new(size_t size) { 24 | return (void*)0x100; 25 | } 26 | 27 | void operator delete(void *) __attribute__((weak)); 28 | void operator delete(void * ptr) { } 29 | extern "C" void atexit( void ) __attribute__((weak)); 30 | extern "C" void atexit( void ) { } 31 | 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Eugene Hutorny 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/ccs.hpp: -------------------------------------------------------------------------------- 1 | /************************************************************************/ 2 | /* ccs.hpp core configuration definitions */ 3 | /************************************************************************/ 4 | /* please visist this link for motivations and details */ 5 | /* http://hutorny.in.ua/research/cascaded-configuration-sets-for-c1y */ 6 | #pragma once 7 | namespace configuration { 8 | /* predefined configuration set identifiers */ 9 | 10 | namespace build { 11 | class Default; 12 | class Debug; 13 | } 14 | 15 | namespace target { 16 | class All; 17 | } 18 | 19 | /* sugar for easy selector definition */ 20 | template 21 | struct Is { 22 | typedef Target target; 23 | typedef Build build; 24 | }; 25 | 26 | /** selector of active configuration set for UserClass */ 27 | template 28 | struct Selector : Is {}; 29 | 30 | /* Declaration of main configuration template */ 31 | template::target, 33 | typename = typename Selector::build> 34 | struct Configuration; 35 | } 36 | -------------------------------------------------------------------------------- /tests/esp8266/esp8266_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2004 CodeSourcery, LLC 3 | * 4 | * Permission to use, copy, modify, and distribute this file 5 | * for any purpose is hereby granted without fee, provided that 6 | * the above copyright notice and this notice appears in all 7 | * copies. 8 | * 9 | * This file is distributed WITHOUT ANY WARRANTY; without even the implied 10 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 | */ 12 | 13 | /* THIS IS A COPY OF init.c FROM NEWLIB TO FIX MISSING CALL OF GLOBAL CTORS */ 14 | 15 | /* Handle ELF .{pre_init,init,fini}_array sections. */ 16 | #include 17 | 18 | #ifdef HAVE_INITFINI_ARRAY 19 | 20 | /* These magic symbols are provided by the linker. */ 21 | extern void (*__preinit_array_start []) (void) __attribute__((weak)); 22 | extern void (*__preinit_array_end []) (void) __attribute__((weak)); 23 | extern void (*__init_array_start []) (void) __attribute__((weak)); 24 | extern void (*__init_array_end []) (void) __attribute__((weak)); 25 | 26 | extern void _init (void); 27 | 28 | /* Iterate over all the init routines. */ 29 | void 30 | __libc_init_array (void) 31 | { 32 | size_t count; 33 | size_t i; 34 | 35 | count = __preinit_array_end - __preinit_array_start; 36 | for (i = 0; i < count; i++) 37 | __preinit_array_start[i] (); 38 | 39 | _init (); 40 | 41 | count = __init_array_end - __init_array_start; 42 | for (i = 0; i < count; i++) 43 | __init_array_start[i] (); 44 | } 45 | #endif 46 | -------------------------------------------------------------------------------- /chaskey8s.cpp: -------------------------------------------------------------------------------- 1 | /* chaskey8s.cpp - implementation of Chaskey 8 cipher block 2 | * Chaskey algorithm invented by Nicky Mouha http://mouha.be/chaskey/ 3 | * 4 | * Copyright (C) 2017 Eugene Hutorny 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | #include "chaskey.hpp" 27 | namespace crypto { 28 | namespace chaskey { 29 | void Cipher8s::permute() noexcept { 30 | base::permute(); 31 | } 32 | 33 | void Cipher8s::etumrep() noexcept { 34 | base::etumrep(); 35 | } 36 | 37 | void Cipher8s::derive(block_t& v, const block_t& in) noexcept { 38 | base::derive(v,in); 39 | } 40 | 41 | }} 42 | -------------------------------------------------------------------------------- /tests/hosted/miculog.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Eugene Hutorny 3 | * 4 | * miculog.hpp - simple logging facilities 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #include "miculog.hpp" 31 | 32 | namespace miculog { 33 | inline constexpr unsigned char operator+(level lvl) noexcept { 34 | return static_cast(lvl); 35 | } 36 | namespace details { 37 | 38 | static const char * const names[1 + +level::none] = { 39 | "!TRACE: ", 40 | "!DEBUG: ", 41 | "!INFO : ", 42 | "!WARN : ", 43 | "!ERROR: ", 44 | "!FAIL : ", 45 | "!?NONE: " 46 | }; 47 | 48 | void default_appender::log(level lvl, const char* fmt, ...) noexcept { 49 | if( lvl <= level::none ) 50 | fputs(names[+lvl], stdout); 51 | va_list args; 52 | va_start(args, fmt); 53 | vfprintf(stdout, fmt, args); 54 | va_end(args); 55 | } 56 | 57 | }} 58 | -------------------------------------------------------------------------------- /tests/mega2560/arduino.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * main_wiring.cpp 3 | * 4 | * Test environment for wiring based platforms, such as Arduino, Photon, Teensy 5 | */ 6 | #include 7 | #include 8 | 9 | void setup() { 10 | Serial.begin(115200); 11 | Serial.println("Chaskey tests starting"); 12 | pinMode(LED_BUILTIN, OUTPUT); 13 | } 14 | 15 | unsigned long last = 0; 16 | uint8_t toggle = 0; 17 | 18 | 19 | extern bool test(); 20 | extern bool bench(unsigned long); 21 | static unsigned long command(); 22 | 23 | unsigned long milliseconds() { 24 | return millis(); 25 | } 26 | 27 | void loop() { 28 | unsigned long cmd = command(); 29 | if( cmd == 0 ) test(); 30 | else if( cmd > 0 ) bench(cmd); 31 | } 32 | 33 | static unsigned long command() { 34 | unsigned long value = 0; 35 | unsigned char toggle = 0; 36 | int chr; 37 | Serial.println("Enter count for benchmark or hit enter for self-test"); 38 | while( ! Serial.available() ) { 39 | delay(100); 40 | Serial.write((++toggle) & 4 ? "\r:" : "\r."); 41 | digitalWrite(LED_BUILTIN, toggle & 0x10 ? HIGH : LOW); 42 | } 43 | while(true) { 44 | while( ! Serial.available() ) { 45 | delay(100); 46 | digitalWrite(LED_BUILTIN, (++toggle) & 0x10 ? HIGH : LOW); 47 | } 48 | chr = Serial.read(); 49 | Serial.write(chr); 50 | switch( chr ) { 51 | default: 52 | Serial.write("\r?"); 53 | value = 0; 54 | break; 55 | case ' ': 56 | case '\r': 57 | case '\n': 58 | return value; 59 | case '0': 60 | case '1': 61 | case '2': 62 | case '3': 63 | case '4': 64 | case '5': 65 | case '6': 66 | case '7': 67 | case '8': 68 | case '9': value = value * 10 + chr - '0'; break; 69 | } 70 | } 71 | } 72 | 73 | void LogAppender::log(miculog::level lvl, const char* fmt, ...) noexcept { 74 | using typename miculog::level; 75 | char buff[128] = {}; 76 | if( lvl == level::fail ) 77 | Serial.print("FAILED\t:"); 78 | if( lvl == level::error ) 79 | Serial.print("error\t:"); 80 | va_list args; 81 | va_start(args, fmt); 82 | vsprintf(buff, fmt, args); 83 | va_end(args); 84 | Serial.write(buff); 85 | } 86 | 87 | -------------------------------------------------------------------------------- /tests/msp430/msp430.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "msp430.hpp" 5 | #include "hw_memmap.h" 6 | 7 | namespace msp430 { 8 | 9 | static inline constexpr volatile uint16_t& uart_reg( 10 | uart::channel_t chnl, uint16_t off) { 11 | return chnl == uart::channel_t::esci_a0 ? 12 | hwreg16(EUSCI_A0_BASE,off) : hwreg16(EUSCI_A1_BASE,off); 13 | } 14 | 15 | struct brg { 16 | const uint16_t brw; 17 | const uint16_t mctlw; 18 | inline constexpr brg( 19 | uint16_t brw_, 20 | uint8_t brf, 21 | uint8_t brs, 22 | bool os) noexcept 23 | : brw(brw_), 24 | mctlw(brs << 8 | brf << 4 | (os ? UCOS16 : 0)) {} 25 | }; 26 | 27 | static constexpr const brg presets[uart::baudrate_count] = { 28 | /* brw brf brs oversample */ 29 | {138, 0, 0xF7, false}, 30 | { 4, 5, 0x55, true} 31 | }; 32 | 33 | inline void uart::init( 34 | uart::baudrate_t baudrate, 35 | const uart::params& param) const noexcept { 36 | uart_reg(channel, OFS_UCAxCTLW0) = UCSWRST; 37 | uart_reg(channel, OFS_UCAxBRW) = 38 | presets[static_cast(baudrate)].brw; 39 | uart_reg(channel, OFS_UCAxMCTLW) = 40 | presets[static_cast(baudrate)].mctlw; 41 | uart_reg(channel, OFS_UCAxCTLW0) = param.ctlw0; 42 | } 43 | 44 | 45 | bool uart::put(char data, uart::blocking_t blocking) const noexcept { 46 | if( blocking == uart::blocking_t::blocking ) 47 | //Poll for transmit interrupt flag 48 | while(!(uart_reg(channel, OFS_UCAxIFG) & UCTXIFG)); 49 | else 50 | if(!(uart_reg(channel,OFS_UCAxIFG) & UCTXIFG)) return false; 51 | uart_reg(channel, OFS_UCAxTXBUF) = data; 52 | return true; 53 | } 54 | 55 | bool uart::get(char& data, uart::blocking_t blocking) const noexcept { 56 | if( blocking == uart::blocking_t::blocking ) 57 | while(!(uart_reg(channel, OFS_UCAxIFG) & UCRXIFG)); 58 | else 59 | if(!(uart_reg(channel,OFS_UCAxIFG) & UCRXIFG)) return false; 60 | data = uart_reg(channel,OFS_UCAxRXBUF); 61 | return true; 62 | } 63 | 64 | void uart::begin(uart::baudrate_t baudrate, const uart::params & p) const noexcept { 65 | /* msp430fr6989.pdf 6.11.24.1 */ 66 | switch(channel) { 67 | case channel_t::esci_a0: 68 | /* USCI_A0 UART operation P4.3/P4.2 */ 69 | P4SEL0 |= BIT2 | BIT3; /* UCA0TXD */ 70 | P4SEL1 &= ~(BIT2 | BIT3); /* UCA0RXD */ 71 | break; 72 | case channel_t::esci_a1: 73 | P3SEL0 |= BIT4 | BIT5; /* UCA1TXD */ 74 | P3SEL1 &= ~(BIT4 | BIT5); /* UCA1RXD */ 75 | } 76 | init(baudrate, p); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/photon/gcc.opt: -------------------------------------------------------------------------------- 1 | -g3 2 | -gdwarf-2 3 | -O3 4 | -mcpu=cortex-m3 5 | -mthumb 6 | -ffunction-sections 7 | -fdata-sections 8 | -Wall 9 | -Wno-switch 10 | -Wno-error=deprecated-declarations 11 | -fmessage-length=0 12 | -fno-strict-aliasing 13 | -fno-builtin-malloc 14 | -fno-builtin-free 15 | -fno-builtin-realloc 16 | -fno-exceptions 17 | -fno-rtti 18 | -fcheck-new 19 | -std=gnu++14 20 | -DSPARK=1 21 | -DPARTICLE=1 22 | -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 23 | -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 24 | -DSPARK_PLATFORM_NET=BCM9WCDUSI09 25 | -DSTM32_DEVICE 26 | -DSTM32F2XX 27 | -DPLATFORM_THREADING=1 28 | -DPLATFORM_ID=6 29 | -DPLATFORM_NAME=photon 30 | -DUSBD_VID_SPARK=0x2B04 31 | -DUSBD_PID_DFU=0xD006 32 | -DUSBD_PID_CDC=0xC006 33 | -DSPARK_PLATFORM 34 | -DINCLUDE_PLATFORM=1 35 | -DPRODUCT_ID=6 36 | -DPRODUCT_FIRMWARE_VERSION=65535 37 | -DUSE_STDPERIPH_DRIVER 38 | -DDFU_BUILD_ENABLE 39 | -DPARTICLE_NO_ARDUINO_COMPATIBILITY=0 40 | -DSYSTEM_VERSION_STRING=0.6.1 41 | -DRELEASE_BUILD 42 | -DLOG_INCLUDE_SOURCE_INFO=1 43 | -DPARTICLE_USER_MODULE 44 | -DUSE_THREADING=0 45 | -DUSE_SPI=SPI 46 | -DUSE_CS=A2 47 | -DUSE_SPI=SPI 48 | -DUSE_CS=A2 49 | -DUSE_THREADING=0 50 | -DUSER_FIRMWARE_IMAGE_SIZE=0x20000 51 | -DUSER_FIRMWARE_IMAGE_LOCATION=0x80A0000 52 | -DMODULAR_FIRMWARE=1 53 | -DMODULE_VERSION=4 54 | -DMODULE_FUNCTION=5 55 | -DMODULE_INDEX=1 56 | -DMODULE_DEPENDENCY=4,2,105 57 | -D_WINSOCK_H 58 | -D_GNU_SOURCE 59 | -DLOG_MODULE_CATEGORY="\"app\"" 60 | -I/opt/particle/user/inc 61 | -I/opt/particle/wiring/inc 62 | -I/opt/particle/system/inc 63 | -I/opt/particle/services/inc 64 | -I/opt/particle/communication/src 65 | -I/opt/particle/hal/inc 66 | -I/opt/particle/hal/shared 67 | -I/opt/particle/hal/src/photon 68 | -I/opt/particle/hal/src/stm32f2xx 69 | -I/opt/particle/hal/src/stm32 70 | -I/opt/particle/hal/src/photon/api 71 | -I/opt/particle/platform/shared/inc 72 | -I/opt/particle/platform/MCU/STM32F2xx/STM32_USB_Host_Driver/inc 73 | -I/opt/particle/platform/MCU/STM32F2xx/STM32_USB_OTG_Driver/inc 74 | -I/opt/particle/platform/MCU/STM32F2xx/STM32_StdPeriph_Driver/inc 75 | -I/opt/particle/platform/MCU/STM32F2xx/STM32_USB_Device_Driver/inc 76 | -I/opt/particle/platform/MCU/STM32F2xx/SPARK_Firmware_Driver/inc 77 | -I/opt/particle/platform/MCU/shared/STM32/inc 78 | -I/opt/particle/platform/MCU/STM32F2xx/CMSIS/Include 79 | -I/opt/particle/platform/MCU/STM32F2xx/CMSIS/Device/ST/Include 80 | -I/opt/particle/dynalib/inc 81 | -I/opt/particle/user/libraries 82 | -I/opt/particle/hal/src/photon/wiced/network/LwIP/ver1.4.0.rc1/src/include 83 | -I/opt/particle/hal/src/photon/wiced/network/LwIP/WWD/FreeRTOS 84 | -I/opt/particle/hal/src/photon/wiced/WWD/include 85 | -I/opt/particle/hal/src/photon/wiced/network/LwIP/ver1.4.0.rc1/src/include/ipv4 86 | -I/opt/particle/hal/src/photon/wiced/RTOS/FreeRTOS/ver7.5.2/Source/include 87 | -I/opt/particle/hal/src/photon/wiced/RTOS/FreeRTOS/WWD/ARM_CM3/ 88 | -I../compiler/gcc-arm-none-eabi 89 | -I../tests 90 | -I.. 91 | -------------------------------------------------------------------------------- /tests/msp430/msp430_hw.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * msp430_hw.hpp 3 | * 4 | * Created on: Nov 14, 2015 5 | * Author: eugene 6 | */ 7 | 8 | #ifndef MSP430_HW_HPP_ 9 | #define MSP430_HW_HPP_ 10 | #include "hw_memmap.h" 11 | 12 | namespace msp430 { 13 | 14 | static inline constexpr uint16_t gpio_port_addr(uint16_t port) noexcept { 15 | return 16 | #if defined(__MSP430_HAS_PORT1_R__) 17 | port == 1 ? 18 | __MSP430_BASEADDRESS_PORT1_R__ : 19 | #elif defined(__MSP430_HAS_PORT1__) 20 | port == 1 ? 21 | __MSP430_BASEADDRESS_PORT1__ : 22 | #endif 23 | #if defined(__MSP430_HAS_PORT2_R__) 24 | port == 2 ? 25 | __MSP430_BASEADDRESS_PORT2_R__ : 26 | #elif defined(__MSP430_HAS_PORT2__) 27 | port == 2 ? 28 | __MSP430_BASEADDRESS_PORT2__ : 29 | #endif 30 | #if defined(__MSP430_HAS_PORT3_R__) 31 | port == 3 ? 32 | __MSP430_BASEADDRESS_PORT3_R__ : 33 | #elif defined(__MSP430_HAS_PORT3__) 34 | port == 3 ? 35 | __MSP430_BASEADDRESS_PORT3__ : 36 | #endif 37 | #if defined(__MSP430_HAS_PORT4_R__) 38 | port == 4 ? 39 | __MSP430_BASEADDRESS_PORT4_R__ : 40 | #elif defined(__MSP430_HAS_PORT4__) 41 | port == 4 ? 42 | __MSP430_BASEADDRESS_PORT4__ : 43 | #endif 44 | #if defined(__MSP430_HAS_PORT5_R__) 45 | port == 5 ? 46 | __MSP430_BASEADDRESS_PORT5_R__ : 47 | #elif defined(__MSP430_HAS_PORT5__) 48 | port == 5 ? 49 | __MSP430_BASEADDRESS_PORT5__ : 50 | #endif 51 | #if defined(__MSP430_HAS_PORT6_R__) 52 | port == 6 ? 53 | __MSP430_BASEADDRESS_PORT6_R__: 54 | #elif defined(__MSP430_HAS_PORT6__) 55 | port == 6 ? 56 | __MSP430_BASEADDRESS_PORT6__: 57 | #endif 58 | #if defined(__MSP430_HAS_PORT7_R__) 59 | port == 7 ? 60 | __MSP430_BASEADDRESS_PORT7_R__: 61 | #elif defined(__MSP430_HAS_PORT7__) 62 | port == 7 ? 63 | __MSP430_BASEADDRESS_PORT7__: 64 | #endif 65 | #if defined(__MSP430_HAS_PORT8_R__) 66 | port == 8 ? 67 | __MSP430_BASEADDRESS_PORT8_R__: 68 | #elif defined(__MSP430_HAS_PORT8__) 69 | port == 8 ? 70 | __MSP430_BASEADDRESS_PORT8__: 71 | #endif 72 | #if defined(__MSP430_HAS_PORT9_R__) 73 | port == 9 ? 74 | __MSP430_BASEADDRESS_PORT9_R__: 75 | #elif defined(__MSP430_HAS_PORT9__) 76 | port == 9 ? 77 | __MSP430_BASEADDRESS_PORT9__: 78 | #endif 79 | #if defined(__MSP430_HAS_PORT10_R__) 80 | port == 10 ? 81 | __MSP430_BASEADDRESS_PORT10_R__: 82 | #elif defined(__MSP430_HAS_PORT10__) 83 | port == 10 ? 84 | __MSP430_BASEADDRESS_PORT10__ : 85 | #endif 86 | #if defined(__MSP430_HAS_PORT11_R__) 87 | port == 11 ? 88 | __MSP430_BASEADDRESS_PORT11_R__: 89 | #elif defined(__MSP430_HAS_PORT11__) 90 | port == 11 ? 91 | __MSP430_BASEADDRESS_PORT11__: 92 | #endif 93 | #if defined(__MSP430_HAS_PORTJ_R__) 94 | port == 13 ? 95 | __MSP430_BASEADDRESS_PORTJ_R__: 96 | #elif defined(__MSP430_HAS_PORTJ__) 97 | port == 13 ? 98 | __MSP430_BASEADDRESS_PORTJ__: 99 | #endif 100 | 0xFFFF; 101 | } 102 | } 103 | 104 | #endif /* MSP430_HW_HPP_ */ 105 | -------------------------------------------------------------------------------- /tests/miculog.ccs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Eugene Hutorny 3 | * 4 | * miculog.ccs - cascaded configuration for miculog 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | 27 | #pragma once 28 | #include "ccs.hpp" 29 | 30 | namespace miculog { 31 | enum class level : unsigned char { 32 | trace, 33 | debug, 34 | info, 35 | warn, 36 | error, 37 | fail, 38 | none 39 | }; 40 | namespace details { 41 | /* all log calls end up in this function, implemented by the user */ 42 | 43 | struct default_appender { 44 | static void log(level, const char* fmt, ...) noexcept 45 | __attribute__ ((format (printf, 2, 3))); 46 | }; 47 | 48 | template 49 | struct enumset; 50 | 51 | template 52 | struct enumset { 53 | static constexpr const V value = 0; 54 | }; 55 | 56 | template 57 | static constexpr const V shift(int v, T t) noexcept { 58 | return static_cast(v) << static_cast(t); 59 | } 60 | 61 | template 62 | struct enumset { 63 | static constexpr const V value = { shift(1, t) }; 64 | }; 65 | 66 | template 67 | struct enumset { 68 | static constexpr const V value = { 69 | (shift(1, t)) | enumset::value }; 70 | }; 71 | 72 | template 73 | static inline bool constexpr is_set(V v, level t) noexcept { 74 | return v & (static_cast(1) << static_cast(t)); 75 | } 76 | } 77 | 78 | template 79 | struct appender: public details::default_appender {}; 80 | 81 | template 82 | struct From { 83 | static constexpr const unsigned char value = { 84 | t == level::none ? 0 : details::shift(-1, t) }; 85 | }; 86 | 87 | template 88 | struct Levels: details::enumset {}; 89 | 90 | template 91 | struct ClassLogLevels : From { }; 92 | 93 | template 94 | struct ClassLogLevels : From{}; 95 | 96 | 97 | } -------------------------------------------------------------------------------- /tests/esp8266/esp8266.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Eugene Hutorny 3 | * 4 | * teensy.cpp - cojson tests, Teensy 3.1 specific implementation 5 | * 6 | * This file is part of COJSON Library. http://hutorny.in.ua/projects/cojson 7 | * 8 | * The COJSON Library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public License v2 10 | * as published by the Free Software Foundation; 11 | * 12 | * The COJSON Library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | * See the GNU Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with the COJSON Library; if not, see 19 | * . 20 | */ 21 | #include 22 | #include 23 | #include 24 | #include "esp8266_user.h" 25 | 26 | static struct Console { 27 | inline void write(const char* s) noexcept { serial_write(s); } 28 | inline void write(char c) noexcept { serial_writec(c); } 29 | inline bool available() noexcept { return serial_available(); } 30 | char read() noexcept { return serial_read(); } 31 | inline Console() { 32 | } 33 | static inline void attach() { 34 | user_rx_installcb(rx_callback); 35 | user_hb_installcb(hb_callback); 36 | } 37 | private: 38 | bool command(unsigned len); 39 | static void rx_callback(unsigned len); 40 | static void hb_callback(int cnt) { 41 | if( ! busy ) { 42 | serial_write(cnt & 1 ? "\r:" : "\r."); 43 | } 44 | } 45 | static bool busy; 46 | } Serial; 47 | 48 | void Console::rx_callback(unsigned len) { 49 | busy = true; 50 | busy = Serial.command(len); 51 | } 52 | 53 | void console_attach() { 54 | Console::attach(); 55 | } 56 | 57 | bool Console::busy = false; 58 | extern bool test(); 59 | extern bool bench(unsigned long); 60 | 61 | bool Console::command(unsigned len) { 62 | static unsigned long value = 0; 63 | int chr; 64 | while(len--) { 65 | chr = read(); 66 | switch( chr ) { 67 | default: write("\r?"); break; 68 | case '\r': 69 | case '\n': 70 | if( value ) { 71 | system_soft_wdt_stop(); 72 | bench(value); 73 | system_soft_wdt_restart(); 74 | } 75 | else test(); 76 | value = 0; 77 | return false; 78 | case '\t': 79 | case '0': 80 | case '1': 81 | case '2': 82 | case '3': 83 | case '4': 84 | case '5': 85 | case '6': 86 | case '7': 87 | case '8': 88 | case '9': value = value * 10 + chr - '0'; break; 89 | } 90 | } 91 | return true; 92 | } 93 | 94 | unsigned long milliseconds() { 95 | return system_get_time() / 1000; 96 | } 97 | 98 | 99 | extern "C" void ets_printf(const char*, ...); 100 | 101 | void LogAppender::log(miculog::level lvl, const char* fmt, ...) noexcept { 102 | using typename miculog::level; 103 | switch( lvl ) { 104 | case level::fail: 105 | ets_printf("FAILED\t:"); 106 | break; 107 | case level::error: 108 | ets_printf("error\t:"); 109 | break; 110 | default:; 111 | } 112 | va_list args; 113 | va_start(args, fmt); 114 | ets_vprintf(ets_putc, fmt, args); 115 | va_end(args); 116 | } 117 | -------------------------------------------------------------------------------- /tests/msp430/hw_memmap.h: -------------------------------------------------------------------------------- 1 | /* --COPYRIGHT--,BSD 2 | * Copyright (c) 2014, Texas Instruments Incorporated 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 16 | * * Neither the name of Texas Instruments Incorporated nor the names of 17 | * its contributors may be used to endorse or promote products derived 18 | * from this software without specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 27 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 29 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 30 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * --/COPYRIGHT--*/ 32 | #ifndef __HW_MEMMAP__ 33 | #define __HW_MEMMAP__ 34 | 35 | #define __DRIVERLIB_MSP430FR5XX_6XX_FAMILY__ 36 | //***************************************************************************** 37 | // 38 | // Include device specific header file 39 | // 40 | //***************************************************************************** 41 | #include 42 | 43 | #include "msp430fr5xx_6xxgeneric.h" 44 | 45 | #include "stdint.h" 46 | #include "stdbool.h" 47 | 48 | //***************************************************************************** 49 | // 50 | // SUCCESS and FAILURE for API return value 51 | // 52 | //***************************************************************************** 53 | #define STATUS_SUCCESS 0x01 54 | #define STATUS_FAIL 0x00 55 | 56 | //***************************************************************************** 57 | // 58 | // Macro for enabling assert statements for debugging 59 | // 60 | //***************************************************************************** 61 | #define NDEBUG 62 | 63 | //***************************************************************************** 64 | // 65 | // Macros for hardware access 66 | // 67 | //***************************************************************************** 68 | #define HWREG32(x) \ 69 | (*((volatile uint32_t *)((uint16_t)x))) 70 | #define HWREG16(x) \ 71 | (*((volatile uint16_t *)((uint16_t)x))) 72 | #define HWREG8(x) \ 73 | (*((volatile uint8_t *)((uint16_t)x))) 74 | 75 | #endif // #ifndef __HW_MEMMAP__ 76 | -------------------------------------------------------------------------------- /tests/esp8266/esp8266_user.c: -------------------------------------------------------------------------------- 1 | #include "ets_sys.h" 2 | #include "osapi.h" 3 | #include "gpio.h" 4 | #include "os_type.h" 5 | #include "user_config.h" 6 | #include "driver/uart.h" 7 | #include "esp8266_user.h" 8 | 9 | #define USER_RX_QUEUE_LEN 1 10 | os_event_t user_rx_queue[USER_RX_QUEUE_LEN]; 11 | #define BUF_SPAN (8) 12 | #define BUF_SIZE (1<sig == 0){ 50 | uint8 fifo_len = (READ_PERI_REG(UART_STATUS(UART0))>>UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; 51 | uint8 d_tmp = 0; 52 | uint8 idx=0; 53 | for(idx=0;idx 7 | #include "chaskey.hpp" 8 | #ifndef CHASKEY_HEAD2HEAD_TEST 9 | #include "chaskey.h" 10 | #endif 11 | 12 | namespace crypto { 13 | namespace chaskey { 14 | /** single chunk formatter to optimize access to a single chunk of data */ 15 | template 16 | class single_chunk; 17 | 18 | /* little-endian version with direct access to the data */ 19 | template<> 20 | class single_chunk : public details::simple_formatter { 21 | public: 22 | typedef details::simple_formatter base; 23 | using typename base::block_t; 24 | using typename base::size_t; 25 | inline void attach(const uint8_t* msg, size_t len) noexcept { 26 | size_t blocks = len ? (len - 1) / sizeof(block_t) : 0; 27 | raw = reinterpret_cast(msg); 28 | end = raw + blocks; 29 | size_t tail = (len % sizeof(block_t)); 30 | if( tail || ! len ) { 31 | msg += len - tail; 32 | base::append(msg, tail); /* side effect on tail and msg */ 33 | base::pad(1); 34 | las = &base::block(); 35 | padded = true; 36 | } else { 37 | las = raw + blocks; 38 | padded = false; 39 | } 40 | } 41 | inline const block_t& block() const noexcept { 42 | return *raw; 43 | } 44 | inline void reset() noexcept { 45 | base::reset(); 46 | raw = &base::block(); 47 | } 48 | inline void next() noexcept { 49 | raw++; 50 | } 51 | inline const block_t& last() noexcept { 52 | return *las; 53 | } 54 | /* returns true if has more that one block to process */ 55 | inline bool has() const noexcept { 56 | return raw < end; 57 | } 58 | inline bool pad() const noexcept { 59 | return padded; 60 | } 61 | private: 62 | const block_t* raw; 63 | const block_t* end; 64 | const block_t* las; 65 | bool padded; 66 | }; 67 | 68 | 69 | /* big-endian full-buffered version */ 70 | 71 | template<> 72 | class single_chunk : public details::simple_formatter { 73 | public: 74 | typedef details::simple_formatter base; 75 | using typename base::block_t; 76 | using typename base::size_t; 77 | inline void attach(const uint8_t* amsg, size_t alen) noexcept { 78 | msg=amsg; 79 | len = alen; 80 | base::append(msg, len); 81 | } 82 | inline void next() noexcept { 83 | reset(); 84 | base::append(msg, len); 85 | } 86 | inline const block_t& last() noexcept { 87 | return base::block(); 88 | } 89 | inline bool has() const noexcept { 90 | return len; 91 | } 92 | inline bool pad() noexcept { 93 | if( full() ) return false; 94 | base::pad(1); 95 | return true; 96 | } 97 | private: 98 | const uint8_t* msg; 99 | size_t len; 100 | bool padded; 101 | }; 102 | 103 | /** 104 | * Chaskey8Alt - implements Chaskey message authentication algorithm 105 | * optimized to work with single chunk of data 106 | */ 107 | class Chaskey8Alt : public Chaskey8 { 108 | public: 109 | typedef uint8_t tag_t[sizeof(block_t)]; 110 | /** 111 | * computes message digest, and writes results to tag 112 | */ 113 | void sign(tag_t& tag, const uint8_t* msg, uint_fast16_t len, 114 | const block_t& key, const block_t& subkey1, 115 | const block_t& subkey2) noexcept { 116 | single_chunk<> buff; 117 | init(key); 118 | buff.attach(msg, len); 119 | const block_t* finalkey = &subkey1; 120 | while( buff.has() ) { 121 | *this ^= buff.block(); 122 | permute(); 123 | buff.next(); 124 | }; 125 | if( buff.pad() ) 126 | finalkey = &subkey2; 127 | *this ^= buff.last(); 128 | *this ^= *finalkey; 129 | permute(); 130 | *this ^= *finalkey; 131 | buff.final(*this); 132 | Block::cast(&tag) = v; 133 | } 134 | }; 135 | }} 136 | using namespace crypto::chaskey; 137 | 138 | inline const Chaskey8::block_t& cast(const uint32_t *key) noexcept { 139 | return * reinterpret_cast(key); 140 | } 141 | inline Chaskey8::block_t & cast(uint32_t *key) noexcept { 142 | return * reinterpret_cast(key); 143 | } 144 | __attribute__((weak)) 145 | void subkeys(uint32_t k1[4], uint32_t k2[4], const uint32_t k[4]) { 146 | const Chaskey8::block_t & key(cast(k)); 147 | Chaskey8::Block & key1(Chaskey8::cast(k1)); 148 | Chaskey8::Block & key2(Chaskey8::cast(k2)); 149 | Chaskey8::derive(key1, key); 150 | Chaskey8::derive(key2, key1); 151 | } 152 | 153 | __attribute__((weak)) 154 | void chaskey(uint8_t *tag, uint32_t taglen, const uint8_t *m, const uint32_t mlen, 155 | const uint32_t k[4], const uint32_t k1[4], const uint32_t k2[4]) { 156 | assert(taglen<=sizeof(Chaskey8::tag_t)); 157 | Chaskey8Alt cipher; 158 | cipher.sign(*reinterpret_cast(tag), m, mlen, 159 | cast(k), cast(k1), cast(k2)); 160 | } 161 | 162 | void (*chaskey_cpp)(uint8_t *, uint32_t, const uint8_t *, const uint32_t, 163 | const uint32_t [4], const uint32_t [4], const uint32_t [4]) = &chaskey; 164 | 165 | void (*subkeys_cpp)(uint32_t [4], uint32_t [4], const uint32_t [4]) = &subkeys; 166 | -------------------------------------------------------------------------------- /tests/msp430/msp430fr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Eugene Hutorny 3 | * 4 | * msp430fr.cpp - chaskey tests, MSP430 specific implementation (not finished) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "miculog.hpp" 12 | #include 13 | #include "msp430fr5xx_6xxgeneric.h" 14 | 15 | #include "msp430.hpp" 16 | 17 | 18 | using namespace msp430; 19 | constexpr uart tty(msp430::uart::channel_t::esci_a0); 20 | constexpr uart aux(msp430::uart::channel_t::esci_a1); 21 | using led_red = gpio::port::pin<0>; 22 | using led_grn = gpio::port::pin<7>; 23 | 24 | extern miculog::Log log; 25 | 26 | 27 | inline bool tty_get(char& c) noexcept { 28 | return tty.get(c, aux.blocking_t::blocking); 29 | } 30 | inline bool tty_peek(char& c) noexcept { 31 | return tty.get(c, aux.blocking_t::non_blocking); 32 | } 33 | 34 | static inline unsigned now() noexcept { return TA2R; } 35 | 36 | 37 | static inline volatile 38 | bool elapsed(unsigned period, unsigned& since) noexcept { 39 | if(period + since < now()) return false; 40 | since = now(); 41 | return true; 42 | } 43 | 44 | static unsigned last = 0; 45 | 46 | static unsigned long command() { 47 | unsigned long value = 0; 48 | unsigned short chr_cnt = 0; 49 | char chr; 50 | tty.put("Enter count for benchmark or hit enter for self-test\n"); 51 | while( ! tty_peek(chr) ) { 52 | if( elapsed(1000,last) ) { 53 | last = now(); 54 | led_red::tgl(); 55 | tty.put(++chr_cnt & 1 ? "\r:" : "\r."); 56 | } 57 | } 58 | 59 | while(true) { 60 | led_grn::set(); 61 | tty.put(chr); 62 | switch( chr ) { 63 | default: 64 | tty.put("\r?"); 65 | value = 0; 66 | break; 67 | case ' ': 68 | case '\r': 69 | case '\n': 70 | led_grn::clr(); 71 | return value; 72 | case '0': 73 | case '1': 74 | case '2': 75 | case '3': 76 | case '4': 77 | case '5': 78 | case '6': 79 | case '7': 80 | case '8': 81 | case '9': value = value * 10 + chr - '0'; break; 82 | } 83 | while( ! tty_peek(chr) ) { 84 | if( elapsed(1000, last) ) 85 | led_grn::tgl(); 86 | } 87 | } 88 | } 89 | 90 | static inline void init_gpio() { 91 | gpio::port::init(); 92 | gpio::port::init(); 93 | gpio::port::init(); 94 | gpio::port::init(); 95 | gpio::port::init(); 96 | gpio::port::init(); 97 | gpio::port::init(); 98 | gpio::port::init(); 99 | gpio::port::init(); 100 | /* set function for LED pins */ 101 | led_red::sel(); 102 | led_grn::sel(); 103 | /* Bit 4 Reserved Reserved. Must be written as 1. */ 104 | SFRRPCR = 0x10 | 105 | SYSRSTRE | SYSRSTUP; /* no NMI, pullup */ 106 | 107 | } 108 | static inline void init_clock() { 109 | // Set DCO frequency to default 8MHz 110 | clocks::dco::setup(clocks::dco::frequency_t::_8MHz); 111 | // Configure MCLK and SMCLK to default 8MHz 112 | clocks::mclk::init(clocks::divider_t::_1); 113 | clocks::smclk::init(clocks::divider_t::_1); 114 | clocks::aclk::init(clocks::divider_t::_1); 115 | 116 | /* TA2 clocked from ACLK which is clocked from VLO (10 KHz) 117 | * TASSEL = 01 118 | * ID = 2 119 | * IDEX = 4 120 | * Timer Mode = 01 Continuous 121 | * After programming ID or TAIDEX bits, set the TACLR 122 | * 123 | * If two timers connected use 16.2.4.1.1 Capture Initiated by Software 124 | * 125 | * */ 126 | TA2CTL = 0x100 | ID_1 | MC_2; 127 | TA2EX0 = TAIDEX_4; 128 | TA2CTL |= TACLR; 129 | } 130 | 131 | void setup() { 132 | WDTCTL = WDTPW | WDTHOLD | WDTCNTCL | WDTSSEL__VLO; // Stop watchdog timer 133 | init_gpio(); 134 | pmm::unlockLPM5(); 135 | init_clock(); 136 | tty.begin(tty.baudrate_t::_115200); 137 | aux.begin(aux.baudrate_t::_115200); 138 | tty.put("\nChaskey tests starting\n"); 139 | aux.put("\nChaskey tests starting\n"); 140 | aux.put("Primary output is set to another UART\n"); 141 | } 142 | 143 | extern bool test(); 144 | extern bool bench(unsigned long); 145 | 146 | 147 | 148 | void loop() { 149 | unsigned long cmd = command(); 150 | if( cmd == 0 ) { 151 | log.warn("Starting self-test\n"); 152 | test(); 153 | } 154 | else { 155 | log.warn("Starting benchmark for %lu\n", cmd); 156 | bench(cmd); 157 | } 158 | } 159 | 160 | void LogAppender::log(miculog::level lvl, const char* fmt, ...) noexcept { 161 | using typename miculog::level; 162 | char buff[128] = {}; 163 | if( lvl == level::fail ) 164 | tty.put("FAILED\t:"); 165 | if( lvl == level::error ) 166 | tty.put("error\t:"); 167 | va_list args; 168 | va_start(args, fmt); 169 | vsprintf(buff, fmt, args); /* use of vsprintf blows up binary size out of small constraints */ 170 | tty.put(buff); 171 | va_end(args); 172 | } 173 | 174 | volatile unsigned long milliseconds() { 175 | return TA2R; 176 | } 177 | 178 | int main(void) { 179 | setup(); 180 | while(true) loop(); 181 | return 0; 182 | } 183 | 184 | -------------------------------------------------------------------------------- /tests/miculog.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 Eugene Hutorny 3 | * 4 | * miculog.hpp - simple logging facilities 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | /* 27 | * Simple and configurable logging facilities 28 | * 29 | * Concepts 30 | * Classes defined here facilitate logging functionality with 31 | * compile-time configurable levels and appenders on per-user-class basis. 32 | * Logging statement with opted off levels are completely removed from 33 | * generated code by the compiler on optimization phase. If logging is 34 | * turned off completely, compiler builds application without any appenders 35 | * provided 36 | * 37 | * Usage 38 | * Define a static instance of Log class in the compilation unit where it will 39 | * be used: 40 | * 41 | * static miculog::Log log; 42 | * 43 | * Use methods, available in log: 44 | * 45 | * log.error("error code:%d\n", err); 46 | * 47 | * This will emit log statements ending up in default appender, which 48 | * calls vprintf for levels error and fail 49 | * 50 | * To change enabled levels, specialize template ClassLogLevels 51 | * as the following: 52 | * 53 | * namespace miculog { 54 | * template<> struct ClassLogLevels : 55 | * Levels {}; } 56 | * 57 | * To change appender specialize template appender as the following: 58 | * 59 | * namespace miculog { 60 | * template<> struct appender { 61 | * static void log(const char* fmt, ...) noexcept; 62 | * };} 63 | * 64 | * and implement appender::log 65 | * 66 | * Generally, you may add these template specializations in any place in 67 | * your code before the actual instantiation of template Log, 68 | * Recommended practice is to include them in your own copy of 69 | * configuration.h file, which should be found in the include path 70 | * before the one provided with this library 71 | * 72 | * You may also replace default appender with a suitable implementation 73 | * simply by removing miculog.cpp from the build and providing your own 74 | * implementation elsewhere 75 | */ 76 | #pragma once 77 | #include 78 | #include "miculog.ccs" 79 | namespace miculog { 80 | 81 | template 82 | struct Log { 83 | using current = typename configuration::Selector; 84 | typedef miculog::appender appender; 85 | 86 | static inline constexpr const auto enabled(level lvl) { 87 | return details::is_set(levels, lvl); 88 | } 89 | template 90 | inline static void trace(const char* fmt, T ... args) noexcept { 91 | if( enabled(level::trace) ) 92 | appender::log(level::trace, fmt, args...); 93 | } 94 | template 95 | inline static void debug(const char* fmt, T ... args) noexcept { 96 | if( enabled(level::debug) ) 97 | appender::log(level::debug, fmt, args...); 98 | } 99 | template 100 | inline static void info(const char* fmt, T ... args) noexcept { 101 | if( enabled(level::info) ) 102 | appender::log(level::info, fmt, args...); 103 | } 104 | template 105 | inline static void warn(const char* fmt, T ... args) noexcept { 106 | if( enabled(level::warn) ) 107 | appender::log(level::warn, fmt, args...); 108 | } 109 | template 110 | inline static void error(const char* fmt, T ... args) noexcept { 111 | if( enabled(level::error) ) 112 | appender::log(level::error, fmt, args...); 113 | } 114 | template 115 | inline static void fail(const char* fmt, T ... args) noexcept { 116 | if( enabled(level::fail) ) 117 | appender::log(level::fail, fmt, args...); 118 | } 119 | template 120 | inline static void warn_if(Bool cond, const char* fmt, T ... args) 121 | noexcept { 122 | if( enabled(level::warn) ) 123 | if (cond) 124 | appender::log(level::warn, fmt, args...); 125 | } 126 | template 127 | inline static void error_if(Bool cond, const char* fmt, T ... args) 128 | noexcept { 129 | if( enabled(level::error) ) 130 | if( cond ) 131 | appender::log(level::error, fmt, args...); 132 | } 133 | template 134 | inline static void fail_if(Bool cond, const char* fmt, T ... args) 135 | noexcept { 136 | if( enabled(level::fail) ) 137 | if( cond ) 138 | appender::log(level::fail, fmt, args...); 139 | } 140 | private: 141 | static constexpr unsigned char levels = 142 | ClassLogLevels::value; 143 | }; 144 | } 145 | 146 | -------------------------------------------------------------------------------- /tests/chaskey.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Chaskey Cipher Demo 6 | 7 | 8 | 9 | 184 | 185 | 186 |
187 |

This page provides testing and demonstration facilities for 188 | Chaskey Cipher algorithm in 189 | 190 | MAC, CBC and 191 | 192 | CLOC modes 193 |

194 | 195 | 196 | 197 |
198 | 199 | 204 | 205 | 206 | 207 |
208 |
209 | 210 | 211 | 212 |
213 |
214 | 215 | 216 |
217 |
218 |
219 | 220 | 224 |
225 |
226 | 227 | 228 | 229 |
230 |
231 |
232 | 233 | 234 |
235 |
236 |
237 | 238 |
239 | 252 | 253 | -------------------------------------------------------------------------------- /tests/esp8266/eagle.app.v6.mod.ld: -------------------------------------------------------------------------------- 1 | /* This linker script generated from xt-genldscripts.tpp for LSP . */ 2 | /* Linker Script for ld -N */ 3 | MEMORY 4 | { 5 | dport0_0_seg : org = 0x3FF00000, len = 0x10 6 | dram0_0_seg : org = 0x3FFE8000, len = 0x14000 7 | iram1_0_seg : org = 0x40100000, len = 0x8000 8 | irom0_0_seg : org = 0x40210000, len = 0x80000 9 | } 10 | 11 | PHDRS 12 | { 13 | dport0_0_phdr PT_LOAD; 14 | dram0_0_phdr PT_LOAD; 15 | dram0_0_bss_phdr PT_LOAD; 16 | iram1_0_phdr PT_LOAD; 17 | irom0_0_phdr PT_LOAD; 18 | } 19 | 20 | 21 | /* Default entry point: */ 22 | ENTRY(call_user_start) 23 | EXTERN(_DebugExceptionVector) 24 | EXTERN(_DoubleExceptionVector) 25 | EXTERN(_KernelExceptionVector) 26 | EXTERN(_NMIExceptionVector) 27 | EXTERN(_UserExceptionVector) 28 | PROVIDE(_memmap_vecbase_reset = 0x40000000); 29 | /* Various memory-map dependent cache attribute settings: */ 30 | _memmap_cacheattr_wb_base = 0x00000110; 31 | _memmap_cacheattr_wt_base = 0x00000110; 32 | _memmap_cacheattr_bp_base = 0x00000220; 33 | _memmap_cacheattr_unused_mask = 0xFFFFF00F; 34 | _memmap_cacheattr_wb_trapnull = 0x2222211F; 35 | _memmap_cacheattr_wba_trapnull = 0x2222211F; 36 | _memmap_cacheattr_wbna_trapnull = 0x2222211F; 37 | _memmap_cacheattr_wt_trapnull = 0x2222211F; 38 | _memmap_cacheattr_bp_trapnull = 0x2222222F; 39 | _memmap_cacheattr_wb_strict = 0xFFFFF11F; 40 | _memmap_cacheattr_wt_strict = 0xFFFFF11F; 41 | _memmap_cacheattr_bp_strict = 0xFFFFF22F; 42 | _memmap_cacheattr_wb_allvalid = 0x22222112; 43 | _memmap_cacheattr_wt_allvalid = 0x22222112; 44 | _memmap_cacheattr_bp_allvalid = 0x22222222; 45 | PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); 46 | 47 | SECTIONS 48 | { 49 | 50 | .dport0.rodata : ALIGN(4) 51 | { 52 | _dport0_rodata_start = ABSOLUTE(.); 53 | *(.dport0.rodata) 54 | *(.dport.rodata) 55 | _dport0_rodata_end = ABSOLUTE(.); 56 | } >dport0_0_seg :dport0_0_phdr 57 | 58 | .dport0.literal : ALIGN(4) 59 | { 60 | _dport0_literal_start = ABSOLUTE(.); 61 | *(.dport0.literal) 62 | *(.dport.literal) 63 | _dport0_literal_end = ABSOLUTE(.); 64 | } >dport0_0_seg :dport0_0_phdr 65 | 66 | .dport0.data : ALIGN(4) 67 | { 68 | _dport0_data_start = ABSOLUTE(.); 69 | *(.dport0.data) 70 | *(.dport.data) 71 | _dport0_data_end = ABSOLUTE(.); 72 | } >dport0_0_seg :dport0_0_phdr 73 | 74 | .data : ALIGN(4) 75 | { 76 | _data_start = ABSOLUTE(.); 77 | *(.data) 78 | *(.data.*) 79 | *(.gnu.linkonce.d.*) 80 | *(.data1) 81 | *(.sdata) 82 | *(.sdata.*) 83 | *(.gnu.linkonce.s.*) 84 | *(.sdata2) 85 | *(.sdata2.*) 86 | *(.gnu.linkonce.s2.*) 87 | *(.jcr) 88 | _persistent_start = ABSOLUTE(.); 89 | *(.persistent) 90 | _persistent_end = ABSOLUTE(.); 91 | _data_end = ABSOLUTE(.); 92 | } >dram0_0_seg :dram0_0_phdr 93 | 94 | .rodata : ALIGN(4) 95 | { 96 | _rodata_start = ABSOLUTE(.); 97 | *(.sdk.version) 98 | *(.rodata) 99 | *(.rodata.*) 100 | *(.gnu.linkonce.r.*) 101 | *(.rodata1) 102 | __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); 103 | *(.xt_except_table) 104 | *(.gcc_except_table) 105 | *(.gnu.linkonce.e.*) 106 | *(.gnu.version_r) 107 | *(.eh_frame) 108 | __init_array_start = ABSOLUTE(.); 109 | /* C++ constructor and destructor tables, properly ordered: */ 110 | KEEP (*crtbegin.o(.ctors)) 111 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 112 | KEEP (*(SORT(.ctors.*))) 113 | KEEP (*(.ctors)) 114 | __init_array_end = ABSOLUTE(.); 115 | KEEP (*crtbegin.o(.dtors)) 116 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 117 | KEEP (*(SORT(.dtors.*))) 118 | KEEP (*(.dtors)) 119 | /* C++ exception handlers table: */ 120 | __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); 121 | *(.xt_except_desc) 122 | *(.gnu.linkonce.h.*) 123 | __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 124 | *(.xt_except_desc_end) 125 | *(.dynamic) 126 | *(.gnu.version_d) 127 | . = ALIGN(4); /* this table MUST be 4-byte aligned */ 128 | _bss_table_start = ABSOLUTE(.); 129 | LONG(_bss_start) 130 | LONG(_bss_end) 131 | _bss_table_end = ABSOLUTE(.); 132 | _rodata_end = ABSOLUTE(.); 133 | } >dram0_0_seg :dram0_0_phdr 134 | 135 | .bss ALIGN(8) (NOLOAD) : ALIGN(4) 136 | { 137 | . = ALIGN (8); 138 | _bss_start = ABSOLUTE(.); 139 | *(.dynsbss) 140 | *(.sbss) 141 | *(.sbss.*) 142 | *(.gnu.linkonce.sb.*) 143 | *(.scommon) 144 | *(.sbss2) 145 | *(.sbss2.*) 146 | *(.gnu.linkonce.sb2.*) 147 | *(.dynbss) 148 | *(.bss) 149 | *(.bss.*) 150 | *(.gnu.linkonce.b.*) 151 | *(COMMON) 152 | . = ALIGN (8); 153 | _bss_end = ABSOLUTE(.); 154 | _heap_start = ABSOLUTE(.); 155 | /* _stack_sentry = ALIGN(0x8); */ 156 | } >dram0_0_seg :dram0_0_bss_phdr 157 | /* __stack = 0x3ffc8000; */ 158 | 159 | .text : ALIGN(4) 160 | { 161 | _stext = .; 162 | _text_start = ABSOLUTE(.); 163 | *(.UserEnter.text) 164 | . = ALIGN(16); 165 | *(.DebugExceptionVector.text) 166 | . = ALIGN(16); 167 | *(.NMIExceptionVector.text) 168 | . = ALIGN(16); 169 | *(.KernelExceptionVector.text) 170 | LONG(0) 171 | LONG(0) 172 | LONG(0) 173 | LONG(0) 174 | . = ALIGN(16); 175 | *(.UserExceptionVector.text) 176 | LONG(0) 177 | LONG(0) 178 | LONG(0) 179 | LONG(0) 180 | . = ALIGN(16); 181 | *(.DoubleExceptionVector.text) 182 | LONG(0) 183 | LONG(0) 184 | LONG(0) 185 | LONG(0) 186 | . = ALIGN (16); 187 | *(.entry.text) 188 | *(.init.literal) 189 | *(.init) 190 | *(.literal .text .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 191 | *(.fini.literal) 192 | *(.fini) 193 | *(.gnu.version) 194 | _text_end = ABSOLUTE(.); 195 | _etext = .; 196 | } >iram1_0_seg :iram1_0_phdr 197 | 198 | .lit4 : ALIGN(4) 199 | { 200 | _lit4_start = ABSOLUTE(.); 201 | *(*.lit4) 202 | *(.lit4.*) 203 | *(.gnu.linkonce.lit4.*) 204 | _lit4_end = ABSOLUTE(.); 205 | . = ALIGN(4096); 206 | _irom0_user_start = ABSOLUTE(.); 207 | KEEP(*(.irom0.user)) 208 | } >iram1_0_seg :iram1_0_phdr 209 | 210 | .irom0.text : ALIGN(4) 211 | { 212 | _irom0_text_start = ABSOLUTE(.); 213 | *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) 214 | *(.literal.* .text.*) 215 | _irom0_text_end = ABSOLUTE(.); 216 | } >irom0_0_seg :irom0_0_phdr 217 | } 218 | 219 | /* get ROM code address */ 220 | INCLUDE "eagle.rom.addr.v6.ld" 221 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Chaskey cipher 2 | 3 | Chaskey is a lightweight 128-bit encryption algorithm 4 | (please follow this link for details http://mouha.be/chaskey/)
5 | This project provides C++ and JavaScript implementations of Chaskey algorithm with two modes of operations: CBC and MAC.
6 | Design of both C++ and JavaScript versions follows high-granular decomposition on the following abstractions: 7 | 8 | * Block – a block of bits stored as an array of integers (32x4) 9 | * Formatter – formats input string of bits as blocks, either buffering them or with zero-copy direct access 10 | * Cipher – implements forward and reverse transformations of the underlying block 11 | * Cbc – Cipher Block Chaining mode of operation 12 | * Mac – Message Authentication mode of operation 13 | * Cloc – Confidentiality and Authentication mode of operation, see https://eprint.iacr.org/2014/157.pdf 14 | 15 | In C++ primitives are implemented as templates, so that a cipher instance ultimately appears as `Cbc,Formatter>` or `Mac,Formatter>`, where N is a number of transformation rounds, set equal to 8 in Chaskey8 class.
16 | In JavaScript same primitives are implemented as objects . Online demo is available on http://hutorny.in.ua/chaskey/ 17 | 18 | ## Usage 19 | 20 | ### C++ 21 | 22 | ```c++ 23 | #inlcude 24 | 25 | 26 | // MAC 27 | crypto::chaskey::Cipher8::Mac mac; // instantiate a cipher in MAC mode 28 | mac.set(key); // set the key 29 | mac.init(); // init cipher if instance is reused 30 | mac.update(message,length,false); // make as many calls as needed with any message length 31 | mac.update(message,length,true); // make one final call 32 | mac.write(ouput); // write signature to the output or 33 | mac.verify(tag); // verify against a signature 34 | 35 | // CBC 36 | crypto::chaskey::Cipher8::Cbc cbc; // instantiate a cipher in CBC mode 37 | cbc.set(key); // set the key 38 | cbc.init(nonce, strlen(nonce)); // init cipher with a nonce 39 | while(in) { 40 | char msg[chunk_size]; 41 | size_t len = in.read(msg,sizeof(msg)).gcount(); // read input by chunks 42 | cbc.encrypt(out, (const uint8_t*)msg, len, in.eof()); // and encrypt or 43 | //cbc.encrypt(out, (const uint8_t*)msg, len, in.eof()); // decrypt data 44 | } 45 | 46 | // CLOC 47 | crypto::chaskey::Cipher8::Cloc cloc; // instantiate a cipher in CLOC mode 48 | cloc.set(key); // set the key 49 | cloc.init(); // inity before reusing instance 50 | cloc.update(ad, length, false); // feed AD by chunks 51 | cloc.update(ad, length, true); // feed last AD chunk 52 | cloc.nonce(nonce, length); // apply noce 53 | cloc.encrypt(out, datachunk, false); // feed data by chunks 54 | cloc.encrypt(out, lastdatachunk, true); // feed last data chunk 55 | ``` 56 | 57 | 58 | ### JavaScript 59 | ```javascript 60 | // MAC 61 | var mac = new ChaskeyCipher.Mac(); // instantiate a cipher in MAC mode 62 | mac.set(key); // set the key 63 | var cif = mac.sign(message); // sign the message 64 | 65 | // CBC 66 | var cbc = new ChaskeyCipher.Cbc(); // instantiate a cipher in CBC mode 67 | cbc.set(key); // set the key 68 | cbc.init(nonce); // init cipher with a nonce 69 | var cif = cbc.encrypt(message); // encrypt the message 70 | ``` 71 | ## Perfromace 72 | 73 | Table below lists benchmarking results for 1M operations on a 32-bytes-long message. 74 | 75 | | Mach | F, MHz| Core | Arh | Ref.MAC | ChaCha8 | Cpp MAC | MAC | Encrypt | Decrypt |aes128cloc| CLOC | 76 | |------------|------:|:--------:|-----------|--------:|--------:|--------:|--------:|--------:|--------:|--------:|--------:| 77 | |i586 | 3,400 | i586 | x86_32 | 59 | 137 | 59 | 57 | 55 | 67 | 863 | 186 | 78 | |Linkit Smart| 580 | MT7688 | MIPS 32 le| 1,020 | 1,710 | 890 | 930 | 880 | 960 | 13,600 | 3,780 | 79 | |Carambola2 | 400 | AR9331 | MIPS 32 be|-- N/A --| 2,500 | 1,730 | 1750 | 2,700 | 2,850 | 19,740 | 8,560 | 80 | |Photon | 120 | STM32F | ARM 32 | 3,176 | 8,780 | 2,451 | 2,395 | 2,184 | 2,941 |-- N/A --| 8,784 | 81 | |Teensy3 | 72 | MK20DX | ARM 32 | 6,390 | 12,926 | 5,220 | 5,346 | 5,054 | 6,055 | 193,700 | 15,450 | 82 | |NodeMCU*|80| LX106 | RISC 32 |-- N/A --| 12,500 | 8,570 | 7,670 | 12,200 | 12,000 |-- N/A --| 31,300 | 83 | |MSP430*| 8 | MSP430 | CISC 16 |-- N/A --|-- N/A --| 431,000 | 398,000 | 388,000 | 577,000 |-- N/A --|-- N/A --| 84 | |Arduino Mega*|8 |ATmega2560|AVR 8|764,000 | 270,000 | 900,000 | 752,000 | 738,000 | 827,000 |-- N/A --|3,840,000| 85 | 86 | Values are give in ms, All binaries were compiled with gcc option `-O3` -- Optimize most.
87 | *NodeMCU, MSP430 and Arduino Mega results are extrapolated from tests with 100K operations 88 | 89 | Next table shows same results in normilized form - clock cycles per one operation 90 | 91 | | Mach | F, MHz| Core | Arh | Ref. MAC| ChaCha8 | Cpp MAC | MAC | Encrypt | Decrypt |aes128cloc| CLOC | 92 | |------------|------:|:--------:|-----------|--------:|--------:|--------:|--------:|--------:|--------:|--------:|--------:| 93 | |i586 | 3,400 | i586 | x86_32 | 201 | 466 | 201 | 194 | 187 | 228 | 2934 | 527 | 94 | |Linkit Smart| 580 | MT7688 | MIPS 32 le| 592 | 992 | 516 | 539 | 510 | 557 | 7888 | 1763 | 95 | |Carambola2 | 400 | AR9331 | MIPS 32 be|-- N/A --| 1000 | 692 | 700 | 1080 | 1140 | 7896 | 3000 | 96 | |Photon | 120 | STM32F | ARM 32 | 381 | 1054 | 294 | 287 | 262 | 353 |-- N/A --| 901 | 97 | |Teensy3 | 72 | MK20DX | ARM 32 | 460 | 931 | 376 | 385 | 364 | 436 | 13946 | 1112 | 98 | |NodeMCU | 80 | LX106 | RISC 32 |-- N/A --| 1000 | 686 | 614 | 976 | 960 |-- N/A --| 2504 | 99 | |MSP430 | 8 | MSP430 | CISC 16 |-- N/A --|-- N/A --| 3448 | 3184 | 3104 | 4616 |-- N/A --|-- N/A --| 100 | |Arduino Mega| 8 |ATmega2560| AVR 8 | 6112 | 2160 | 7200 | 6016 | 5904 | 6616 |-- N/A --| 20880 | 101 | 102 | 103 | State size, including the key, dervied keys and formatter's buffer, bytes: 104 | 105 | | Mach | Arh | MAC | CBC | CLOC | 106 | |------------|-----------|--------:|--------:|--------:| 107 | |i586 | x86_32 | 92 | 60 | 80 | 108 | |Linkit Smart| MIPS 32 le| 92 | 60 | 80 | 109 | |Carambola2 | MIPS 32 be| 84 | 52 | 72 | 110 | |Photon | ARM 32 | 92 | 60 | 80 | 111 | |Teensy3 | ARM 32 | 92 | 60 | 80 | 112 | |NodeMCU | RISC 32 | 84 | 52 | 72 | 113 | |Arduino Mega| AVR 8 | 84 | 52 | 72 | 114 | -------------------------------------------------------------------------------- /tests/msp430/msp430.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "msp430_hw.hpp" 4 | 5 | namespace msp430 { 6 | 7 | template 8 | inline constexpr volatile T & hwreg(uint16_t addr) noexcept { 9 | return * reinterpret_cast(addr); 10 | } 11 | 12 | inline constexpr volatile uint16_t & hwreg16(uint16_t base, uint16_t off) noexcept { 13 | return * reinterpret_cast(base + off); 14 | } 15 | 16 | inline constexpr volatile uint8_t & hwreg8(uint16_t base, uint16_t off) noexcept { 17 | return * reinterpret_cast(base + off); 18 | } 19 | 20 | template 21 | struct conditional; 22 | template 23 | struct conditional { typedef A type; }; 24 | template 25 | struct conditional { typedef B type; }; 26 | 27 | 28 | class pmm { 29 | public: 30 | static inline void unlockLPM5() noexcept { 31 | hwreg8(PMM_BASE, OFS_PM5CTL0) &= ~LOCKLPM5; 32 | } 33 | //TODO other methods 34 | private: 35 | pmm(); 36 | }; 37 | 38 | class clocks { 39 | public: 40 | static inline void unlock() noexcept { 41 | hwreg16(CS_BASE, OFS_CSCTL0) = CSKEY; 42 | } 43 | static inline void lock() noexcept { 44 | hwreg8(CS_BASE, OFS_CSCTL0_H) = 0x00; 45 | } 46 | 47 | enum class divider_t { 48 | _1 = 0, 49 | _2 = 1, 50 | _4 = 2, 51 | _8 = 3, 52 | _16 = 4, 53 | _32 = 5, 54 | }; 55 | /************************************************************************ 56 | * Clock Sources * 57 | ************************************************************************/ 58 | /** 59 | * LFXTCLK: Low-frequency oscillator (32768 Hz) 60 | */ 61 | class lfxt { 62 | public: 63 | static constexpr uint16_t ctl2 = 0; 64 | enum class frequency_t : long { 65 | _32768Hz = 32768L, 66 | }; 67 | static constexpr frequency_t frequency = frequency_t::_32768Hz; 68 | }; 69 | /** 70 | * VLOCLK: Internal very-low-power low-frequency oscillator (10-kHz) 71 | */ 72 | class vlo { 73 | public: 74 | static constexpr uint16_t ctl2 = 1; 75 | enum class frequency_t : long { 76 | _10kHz = 10000L, 77 | }; 78 | static constexpr frequency_t frequency = frequency_t::_10kHz; 79 | }; 80 | /** 81 | * DCOCLK: Internal digitally controlled oscillator (1-24MHz) 82 | */ 83 | class dco { 84 | public: 85 | static constexpr uint16_t ctl2 = 3; 86 | enum class frequency_t : long { 87 | _1MHz = 1000000L, 88 | _2M6Hz = 2600000L, 89 | _3M3Hz = 3300000L, 90 | _4MHz = 4000000L, 91 | _5M3Hz = 5300000L, 92 | _6M7Hz = 6700000L, 93 | _8MHz = 8000000L, 94 | _16MHz = 16000000L, 95 | _21MHz = 21000000L, 96 | _24MHz = 24000000L, 97 | }; 98 | struct frequency { 99 | const uint16_t ctl1; 100 | inline constexpr frequency(frequency_t frq) 101 | : ctl1( 102 | frq == frequency_t::_1MHz ? 0x00 : 103 | frq == frequency_t::_2M6Hz ? 0x02 : 104 | frq == frequency_t::_3M3Hz ? 0x04 : 105 | frq == frequency_t::_4MHz ? 0x06 : 106 | frq == frequency_t::_5M3Hz ? 0x08 : 107 | frq == frequency_t::_6M7Hz ? 0x0A : 108 | frq == frequency_t::_8MHz ? 0x0C : 109 | frq == frequency_t::_16MHz ? 0x48 : 110 | frq == frequency_t::_21MHz ? 0x4A : 111 | frq == frequency_t::_24MHz ? 0x4C : 0x00 112 | ) {} 113 | }; 114 | static inline void setup(const frequency & frq) { 115 | clocks::unlock(); 116 | hwreg16(CS_BASE, OFS_CSCTL1) = frq.ctl1; 117 | clocks::lock(); 118 | } 119 | static inline void setup(frequency_t frq) { 120 | setup(frequency(frq)); 121 | } 122 | private: 123 | dco(); 124 | }; 125 | /** 126 | * MODCLK: Internal low-power oscillator (5-MHz) 127 | */ 128 | class mod { 129 | public: 130 | static constexpr uint16_t ctl2 = 4; 131 | enum class frequency_t : long { 132 | _5MHz = 5000000L, 133 | }; 134 | static constexpr frequency_t frequency = frequency_t::_5MHz; 135 | //TODO 136 | }; 137 | class lfmod { 138 | public: 139 | static constexpr uint16_t ctl2 = 2; 140 | enum class frequency_t : long { 141 | _39kHz = 39000L, 142 | }; 143 | static constexpr frequency_t frequency = frequency_t::_39kHz; 144 | //TODO 145 | }; 146 | /** 147 | * HFXTCLK: High-frequency oscillator (4-24-MHz) 148 | */ 149 | class hfxt { 150 | public: 151 | static constexpr uint16_t ctl2 = 5; 152 | //TODO 153 | }; 154 | /************************************************************************ 155 | * Clock Signals (outputs) * 156 | ************************************************************************/ 157 | class aclk { 158 | public: 159 | template 160 | static inline void init(divider_t divider) { 161 | static_assert( 162 | src::ctl2 == lfmod::ctl2 || 163 | src::ctl2 == lfxt::ctl2 || 164 | src::ctl2 == vlo::ctl2, 165 | "Invalid ACLK source"); 166 | clocks::unlock(); 167 | hwreg16(CS_BASE, OFS_CSCTL2) &= ~(SELA_7); 168 | hwreg16(CS_BASE, OFS_CSCTL2) |= src::ctl2 << 8; 169 | hwreg16(CS_BASE, OFS_CSCTL3) &= ~(DIVA0 | DIVA1 | DIVA2); 170 | hwreg16(CS_BASE, OFS_CSCTL3) |= static_cast(divider) << 8; 171 | clocks::lock(); 172 | } 173 | private: 174 | aclk(); 175 | }; 176 | class mclk { 177 | public: 178 | template 179 | static inline void init(divider_t divider) { 180 | static_assert( 181 | src::ctl2 >= lfxt::ctl2 && src::ctl2 <= hfxt::ctl2, 182 | "Invalid MCLK source"); 183 | clocks::unlock(); 184 | hwreg16(CS_BASE, OFS_CSCTL2) &= ~(SELM_7); 185 | hwreg16(CS_BASE, OFS_CSCTL2) |= src::ctl2; 186 | hwreg16(CS_BASE, OFS_CSCTL3) &= ~(DIVM0 | DIVM1 | DIVM2); 187 | hwreg16(CS_BASE, OFS_CSCTL3) |= static_cast(divider); 188 | clocks::lock(); 189 | } 190 | private: 191 | mclk(); 192 | }; 193 | class smclk { 194 | public: 195 | template 196 | static inline void init(divider_t divider) { 197 | static_assert( 198 | src::ctl2 >= lfxt::ctl2 && src::ctl2 <= hfxt::ctl2, 199 | "Invalid SMCLK source"); 200 | clocks::unlock(); 201 | hwreg16(CS_BASE, OFS_CSCTL2) &= ~(SELS_7); 202 | hwreg16(CS_BASE, OFS_CSCTL2) |= src::ctl2 << 4; 203 | hwreg16(CS_BASE, OFS_CSCTL3) &= ~(DIVS0 | DIVS1 | DIVS2); 204 | hwreg16(CS_BASE, OFS_CSCTL3) |= static_cast(divider) << 4; 205 | clocks::lock(); 206 | } 207 | private: 208 | smclk(); 209 | }; 210 | 211 | enum class signal_t { 212 | aclk, /** ACLK: Auxiliary clock */ 213 | mclk, /** MCLK: Master clock */ 214 | smclk, /** SMCLK: Sub-system master clock. */ 215 | modclk, /** MODCLK: Module clock. */ 216 | vloclk /** VLOCLK: VLO clock */ 217 | }; 218 | private: 219 | clocks(); 220 | }; 221 | 222 | 223 | class gpio { 224 | public: 225 | enum class port_t { 226 | p1 = 1, 227 | p2 = 2, 228 | p3 = 3, 229 | p4 = 4, 230 | p5 = 5, 231 | p6 = 6, 232 | p7 = 7, 233 | p8 = 8, 234 | p9 = 9, 235 | p10 = 10, 236 | p11 = 11, 237 | /* 16-bit ports are not implemented 238 | pa = 1, 239 | pb = 3, 240 | pc = 5, 241 | pd = 7, 242 | pe = 9, 243 | pf = 11, */ 244 | pj = 13, 245 | }; 246 | 247 | enum class direction_t { in, out }; 248 | enum class function_t { io, primary, secondary, ternary }; 249 | enum class pull_t { none, up, down }; 250 | 251 | static constexpr uint8_t all = 0xFF; 252 | 253 | template 254 | class port { 255 | public: 256 | static constexpr uint8_t num = static_cast(P); 257 | static constexpr uint16_t address = gpio_port_addr(num); 258 | static_assert(address!=0xFFFF,"Unsupported port"); 259 | template 260 | class pins { 261 | public: 262 | static_assert(M!=0,"Invalid pin mask"); 263 | static constexpr uint16_t shift = (num&1 ?0:8); 264 | static constexpr uint16_t mask = M << shift; 265 | /** select pin function as GPIO */ 266 | static inline void sel() noexcept { 267 | hwreg16(address,OFS_PASEL0) &= ~ mask; 268 | hwreg16(address,OFS_PASEL1) &= ~ mask; 269 | } 270 | static inline void sel(function_t mode) noexcept { 271 | switch( mode ) { 272 | case function_t::io: 273 | sel(); 274 | case function_t::primary: 275 | hwreg16(address,OFS_PASEL0) |= mask; 276 | hwreg16(address,OFS_PASEL1) &= ~ mask; 277 | break; 278 | case function_t::secondary: 279 | hwreg16(address,OFS_PASEL0) &= ~ mask; 280 | hwreg16(address,OFS_PASEL1) |= mask; 281 | break; 282 | case function_t::ternary: 283 | hwreg16(address,OFS_PASELC) |= mask; 284 | } 285 | } 286 | /** set pin direction */ 287 | static inline void dir(direction_t d) noexcept { 288 | if(d == direction_t::in) 289 | hwreg16(address,OFS_PADIR) &= ~ mask; 290 | else 291 | hwreg16(address,OFS_PADIR) |= mask; 292 | } 293 | /** select pin and direction input */ 294 | static inline void in(pull_t pull) noexcept { 295 | sel(); 296 | dir(direction_t::in); 297 | switch(pull) { 298 | case pull_t::none: 299 | hwreg16(address,OFS_PAREN) &= ~mask; 300 | break; 301 | case pull_t::up: 302 | set(); 303 | hwreg16(address,OFS_PAREN) |= mask; 304 | case pull_t::down: 305 | clr(); 306 | hwreg16(address,OFS_PAREN) |= mask; 307 | } 308 | } 309 | /** select pin and direction input */ 310 | static inline void in() noexcept { 311 | sel(); 312 | hwreg16(address,OFS_PADIR) &= ~ mask; 313 | } 314 | /** select pin and direction output */ 315 | static inline void out() noexcept { 316 | sel(); 317 | hwreg16(address,OFS_PADIR) |= mask; 318 | } 319 | static inline void set(bool val) noexcept { 320 | if( val ) 321 | set(); 322 | else 323 | clr(); 324 | } 325 | static inline void set() noexcept { 326 | hwreg16(address,OFS_PAOUT) |= mask; 327 | } 328 | static inline void clr() noexcept { 329 | hwreg16(address,OFS_PAOUT) &= ~mask; 330 | } 331 | static inline void tgl() noexcept { 332 | hwreg16(address,OFS_PAOUT) ^= mask; 333 | } 334 | static inline uint16_t read() noexcept { 335 | return (hwreg16(address,OFS_PAIN) & mask) >> shift; 336 | } 337 | static inline bool get() noexcept { 338 | return hwreg16(address,OFS_PAIN) & mask; 339 | } 340 | //TODO enable/disable interrupt, 341 | private: 342 | pins(); 343 | }; 344 | template 345 | class pin : public pins<(1<{ 346 | static_assert(I<=7,"Pin number out of range"); 347 | }; 348 | template 349 | static inline void init() noexcept { 350 | port

::template pins::clr(); 351 | port

::template pins::out(); 352 | } 353 | private: 354 | port(); 355 | }; 356 | private: 357 | gpio(); 358 | }; 359 | 360 | 361 | class uart { 362 | public: 363 | static constexpr unsigned baudrate_count = 2; 364 | static constexpr unsigned max_channel_count = 2; 365 | enum class baudrate_t { 366 | _57600, 367 | _115200 368 | }; 369 | enum class blocking_t { blocking, non_blocking }; 370 | enum class channel_t : uint_fast8_t { esci_a0, esci_a1 }; 371 | enum class clk_src_t { uclk, aclk, smclk }; 372 | enum class bits_t { _8, _7 }; 373 | enum class parity_t { no, odd, even }; 374 | enum class stopbits_t { one, two }; 375 | 376 | struct params { 377 | uint16_t ctlw0; 378 | inline constexpr params( 379 | clk_src_t clk_src = clk_src_t::smclk, 380 | bits_t bits = bits_t::_8, 381 | parity_t parity = parity_t::no, 382 | stopbits_t stopbits = stopbits_t::one 383 | ) : 384 | ctlw0( 385 | (parity != parity_t::no ? 0x8000 : 0 ) | 386 | (parity == parity_t::even ? 0x4000 : 0 ) | 387 | /* always LSB first */ 388 | (bits == bits_t::_7 ? 0x1000 : 0 ) | 389 | (stopbits == stopbits_t::one ? 0x0800 : 0 ) | 390 | /* always UART mode */ 391 | /* always Asynchronous mode */ 392 | (clk_src == clk_src_t::smclk ? 0x0080 : 0 ) | 393 | (clk_src == clk_src_t::aclk ? 0x0040 : 0 ) 394 | ) { } 395 | }; 396 | 397 | 398 | bool put(char, blocking_t = blocking_t::blocking) const noexcept; 399 | bool get(char&, blocking_t = blocking_t::blocking) const noexcept; 400 | inline constexpr uart(channel_t ch) noexcept : channel(ch) {} 401 | inline uart(channel_t ch, baudrate_t b) noexcept : channel(ch) { begin(b); } 402 | void begin(baudrate_t b, const params & p = params()) const noexcept; 403 | void end() const noexcept; 404 | void put(const char* msg) const noexcept { 405 | while(*msg) put(*msg++); 406 | } 407 | public: 408 | const channel_t channel; 409 | private: 410 | inline void init(uart::baudrate_t,const uart::params&) const noexcept; 411 | uart(); 412 | }; 413 | } 414 | -------------------------------------------------------------------------------- /tests/master.inc: -------------------------------------------------------------------------------- 1 | 2 | const uint8_t master1[] = { 222,202,68,203,71,185,154,219,88,87,129,165,229,233,20,84 }; 3 | const uint8_t master2[] = { 118,224,174,225,96,244,121,47,7,229,134,53,50,125,102,229 }; 4 | const uint8_t master3[] = { 181,138,189,126,50,202,139,119,242,229,175,10,166,232,171,135 }; 5 | const uint8_t master4[] = { 110,122,13,8,84,105,25,52,232,227,37,82,197,121,105,240 }; 6 | const uint8_t master5[] = { 152,133,195,170,129,159,115,98,75,234,31,71,144,111,76,123 }; 7 | const uint8_t master6[] = { 173,161,240,244,218,18,170,68,190,236,248,4,144,147,140,38 }; 8 | const uint8_t master7[] = { 208,231,42,190,67,254,150,98,203,135,73,122,146,167,113,229 }; 9 | const uint8_t master8[] = { 54,189,54,43,74,76,145,168,76,157,212,173,208,25,94,240 }; 10 | const uint8_t master9[] = { 31,72,238,18,104,238,139,142,45,85,187,193,182,105,38,5 }; 11 | const uint8_t master10[] = { 43,255,152,0,109,31,0,111,16,80,119,88,39,130,165,140 }; 12 | const uint8_t master11[] = { 94,178,192,27,86,56,148,42,195,180,12,94,61,200,52,150 }; 13 | const uint8_t master12[] = { 4,211,241,42,135,14,13,245,117,102,113,110,201,248,123,67 }; 14 | const uint8_t master13[] = { 237,114,121,205,231,88,56,34,182,190,62,123,243,252,2,236 }; 15 | const uint8_t master14[] = { 152,187,250,101,26,251,130,193,110,145,149,212,73,39,191,138 }; 16 | const uint8_t master15[] = { 8,12,29,139,151,244,30,9,11,87,218,149,152,92,22,246 }; 17 | const uint8_t master16[] = { 63,11,161,255,230,141,116,83,143,39,65,231,185,126,246,170 }; 18 | const uint8_t master17[] = { 128,245,151,12,111,204,71,170,139,246,19,222,188,68,227,186,60,117,238, 67,4,170,100,95,104,133,87,153,124,212,128,12 }; 19 | const uint8_t master18[] = { 20,77,65,9,13,109,229,60,0,3,186,56,190,90,48,93,186,122,200,16,202,13, 249,218,145,118,223,243,232,130,161,94 }; 20 | const uint8_t master19[] = { 4,57,187,192,5,81,173,237,228,166,182,157,23,47,153,229,109,161,81,4,202, 190,174,72,69,192,98,174,228,68,109,26 }; 21 | const uint8_t master20[] = { 247,71,207,142,146,27,182,0,67,12,235,174,107,70,38,165,186,169,21,187, 8,150,91,122,118,176,192,191,179,73,194,126 }; 22 | const uint8_t master21[] = { 243,51,36,207,216,59,71,0,130,237,118,32,61,223,238,214,136,65,188,52,68, 85,5,116,68,66,7,76,55,14,120,129 }; 23 | const uint8_t master22[] = { 132,15,0,170,117,62,62,232,76,31,204,103,92,224,225,162,224,244,164,189, 11,87,105,241,166,52,122,100,2,131,86,195 }; 24 | const uint8_t master23[] = { 14,90,143,161,121,159,73,147,26,248,88,201,32,241,198,177,88,147,168,10, 51,161,85,86,153,111,216,159,16,252,171,50 }; 25 | const uint8_t master24[] = { 46,137,166,99,10,9,161,19,201,26,190,248,124,221,138,23,18,119,130,83,66, 31,222,255,117,127,135,107,76,241,172,196 }; 26 | const uint8_t master25[] = { 65,96,98,247,42,85,245,104,121,123,23,102,33,130,213,150,181,251,20,191, 179,109,207,13,133,68,150,154,136,143,17,127 }; 27 | const uint8_t master26[] = { 238,77,117,246,217,33,56,85,205,216,1,163,42,189,112,85,104,65,145,65,200, 102,245,25,59,71,59,25,13,18,195,24 }; 28 | const uint8_t master27[] = { 175,155,175,187,29,60,129,58,151,108,248,196,181,96,156,242,113,215,42, 220,224,154,193,233,161,108,45,40,235,201,145,173 }; 29 | const uint8_t master28[] = { 143,58,180,175,39,226,132,151,224,46,144,191,193,230,87,90,46,125,106,225, 132,19,164,242,55,66,21,27,102,81,144,122 }; 30 | const uint8_t master29[] = { 119,60,95,2,38,129,245,99,74,20,55,199,56,162,238,64,44,89,38,8,255,225, 61,149,118,93,166,195,45,242,240,116 }; 31 | const uint8_t master30[] = { 1,140,255,176,19,225,59,182,85,220,132,29,98,57,1,59,33,163,1,83,60,3,232, 118,143,129,29,185,67,97,238,196 }; 32 | const uint8_t master31[] = { 24,236,188,144,157,4,152,167,29,125,37,66,220,168,245,72,50,191,158,70, 190,26,98,59,166,241,193,103,162,233,246,160 }; 33 | const uint8_t master32[] = { 89,121,164,54,147,181,38,167,34,213,245,92,174,126,14,74,144,110,146,95, 56,8,38,153,15,146,74,151,68,134,180,176 }; 34 | const uint8_t master33[] = { 73,13,241,83,220,5,32,25,68,34,116,111,234,221,64,94,20,55,93,242,83,11, 10,59,4,39,196,222,150,229,198,25,197,128,19,78,216,100,168,207,141,207, 175,29,120,24,159,29 }; 35 | const uint8_t master34[] = { 33,223,228,40,106,73,254,13,208,234,230,228,21,44,21,176,85,54,208,216, 187,55,175,198,63,31,60,191,244,84,76,25,115,157,106,166,73,145,102,46, 205,155,243,19,175,205,27,242 }; 36 | const uint8_t master35[] = { 2,229,11,152,59,105,209,14,144,148,195,182,137,119,145,89,143,185,212,8, 92,100,130,107,224,49,77,12,117,89,242,28,147,67,78,81,207,254,255,35,104, 132,93,28,169,163,249,17 }; 37 | const uint8_t master36[] = { 111,183,30,238,137,12,169,152,246,29,162,184,195,17,54,50,158,30,165,140, 231,255,180,250,127,237,85,80,133,88,228,246,97,52,13,120,114,104,192,7, 124,122,226,100,6,215,94,254 }; 38 | const uint8_t master37[] = { 14,133,180,190,194,136,108,116,80,17,2,6,113,129,33,134,150,121,255,152, 92,11,119,196,41,190,114,154,218,224,100,158,252,173,25,54,78,14,152,253, 29,91,51,49,138,133,86,195 }; 39 | const uint8_t master38[] = { 192,149,185,128,17,143,153,163,22,175,42,239,4,247,86,13,193,15,42,76,11, 22,17,17,110,117,125,251,35,30,218,133,190,140,152,74,106,130,88,87,68, 66,174,234,38,215,69,155 }; 40 | const uint8_t master39[] = { 179,112,80,9,233,55,89,134,49,254,119,181,114,238,13,90,158,193,50,2,158, 190,123,71,69,116,117,112,97,248,229,220,189,64,119,137,124,204,221,98, 198,109,77,186,158,215,209,17 }; 41 | const uint8_t master40[] = { 198,176,231,134,208,202,53,132,147,42,126,194,79,209,138,230,207,20,149, 59,47,229,137,27,126,46,234,18,240,100,194,183,201,199,175,190,166,133, 3,96,150,3,238,154,231,126,239,191 }; 42 | const uint8_t master41[] = { 233,227,197,48,11,194,2,96,106,121,24,213,29,135,235,72,143,178,52,214, 40,169,50,108,229,158,18,236,235,164,101,76,21,14,97,243,92,93,225,101, 7,203,68,115,114,79,86,210 }; 43 | const uint8_t master42[] = { 81,215,124,227,54,15,90,239,248,126,23,163,219,13,245,41,30,86,44,249,134, 52,221,127,240,30,141,123,249,8,126,221,226,156,188,235,158,84,165,56,158, 38,168,121,44,161,108,170 }; 44 | const uint8_t master43[] = { 215,156,195,2,145,102,237,9,196,188,163,145,199,35,228,179,28,23,23,249, 85,178,209,135,93,115,173,126,89,48,247,135,179,30,19,89,183,168,203,102, 34,125,207,137,33,84,227,20 }; 45 | const uint8_t master44[] = { 170,236,23,110,135,242,16,240,127,212,197,62,37,130,87,182,134,247,119, 78,61,134,173,159,214,68,203,93,143,247,247,101,163,234,79,216,76,234,227, 48,189,92,125,103,41,47,171,205 }; 46 | const uint8_t master45[] = { 118,70,104,186,35,9,3,77,66,135,235,65,99,242,94,169,113,10,14,103,68,106, 70,10,7,149,242,62,30,100,71,50,149,137,115,146,220,185,252,36,127,222, 232,223,134,45,200,14 }; 47 | const uint8_t master46[] = { 204,140,213,118,192,233,188,143,4,121,4,162,134,98,186,184,2,181,226,224, 108,234,26,82,94,22,96,49,161,202,40,239,201,13,29,73,250,175,210,176,50, 154,87,70,145,107,239,20 }; 48 | const uint8_t master47[] = { 160,68,57,205,169,228,3,107,118,58,91,200,14,166,79,44,219,181,213,27,86, 55,142,117,151,55,78,224,219,81,220,167,183,230,20,196,175,133,245,162, 22,86,144,66,85,214,187,235 }; 49 | const uint8_t master48[] = { 117,117,63,173,126,63,35,138,8,100,76,65,228,108,114,250,70,168,83,107, 133,12,248,18,209,232,62,247,111,94,200,8,174,49,96,108,36,74,30,114,188, 9,136,225,58,105,51,142 }; 50 | const uint8_t master49[] = { 157,1,60,58,10,176,179,199,24,164,77,239,147,96,254,187,168,93,172,8,209, 103,62,122,61,41,35,55,119,107,79,203,4,137,86,53,211,205,221,229,143,71, 131,69,42,4,155,104,19,174,125,223,242,28,65,211,195,41,197,208,9,137,2, 78 }; 51 | const uint8_t master50[] = { 161,212,83,134,155,103,237,212,88,188,177,162,36,16,53,8,52,218,66,239, 202,210,19,78,147,73,227,127,80,128,211,173,204,38,139,59,116,112,213,51, 177,127,54,250,142,13,149,250,174,240,91,131,2,217,59,89,21,210,246,95, 66,231,75,8 }; 52 | const uint8_t master51[] = { 83,56,156,44,197,77,160,143,93,249,83,46,110,207,34,249,155,249,53,121, 66,232,94,72,59,131,210,129,52,13,60,111,5,114,192,85,26,153,9,232,165, 43,102,200,94,173,217,165,181,77,236,252,53,247,89,255,9,16,240,150,230, 180,19,88 }; 53 | const uint8_t master52[] = { 6,9,131,74,104,2,18,36,129,24,75,80,246,121,209,152,247,9,20,55,148,155, 204,85,241,117,128,236,174,73,57,46,62,238,12,196,175,137,79,112,255,52, 218,205,195,135,94,141,213,213,170,144,62,45,91,199,225,185,22,145,155, 75,180,40 }; 54 | const uint8_t master53[] = { 124,27,241,23,212,79,223,87,129,214,34,161,230,240,168,245,116,197,84,67, 41,197,102,155,244,188,36,21,201,194,105,78,28,74,28,212,67,148,94,239, 182,211,130,4,133,147,2,20,91,226,222,159,41,63,206,184,198,205,148,138, 44,41,209,176 }; 55 | const uint8_t master54[] = { 84,104,143,97,29,117,50,48,5,241,116,142,186,158,229,99,95,186,245,237, 197,79,211,176,187,159,127,74,118,17,13,109,247,24,241,3,78,96,255,102, 180,70,228,123,173,59,151,163,110,9,111,199,107,146,179,188,137,61,103, 6,185,247,245,212 }; 56 | const uint8_t master55[] = { 118,110,183,199,103,39,114,241,127,81,119,239,215,127,28,236,115,64,116, 215,102,93,214,207,89,250,200,192,36,25,87,11,44,222,212,149,204,148,44, 255,188,58,157,25,127,24,153,122,92,89,37,133,216,96,141,185,45,115,99, 238,182,33,112,95 }; 57 | const uint8_t master56[] = { 196,213,190,214,69,184,227,220,28,132,237,60,124,167,236,17,174,150,24, 54,114,226,1,196,58,76,25,44,14,102,157,206,13,130,245,161,22,13,213,96, 116,154,246,227,241,139,102,219,182,152,20,131,26,167,38,159,239,236,210, 176,196,156,78,60 }; 58 | const uint8_t master57[] = { 101,147,225,111,103,140,133,149,241,30,23,60,65,248,83,131,194,253,65,198, 18,236,205,213,115,120,194,165,245,70,82,13,125,178,225,131,15,64,240,72, 16,112,128,30,154,57,15,92,25,130,55,222,255,112,188,112,253,246,189,26, 236,207,114,47 }; 59 | const uint8_t master58[] = { 199,161,228,120,85,125,46,243,141,87,89,70,88,113,253,104,68,254,5,237, 79,200,203,144,50,96,208,78,11,252,199,1,138,248,58,220,188,225,124,68, 197,210,249,31,167,107,86,202,222,124,145,187,104,231,99,155,255,235,59, 250,72,223,7,101 }; 60 | const uint8_t master59[] = { 41,194,24,135,196,138,136,5,61,201,81,96,150,96,116,201,105,26,31,123,131, 17,29,120,92,6,70,70,121,35,195,157,218,41,224,155,223,95,191,65,225,217, 172,68,235,37,46,203,73,169,206,26,45,8,20,42,248,142,0,204,80,183,202, 177 }; 61 | const uint8_t master60[] = { 99,45,35,44,153,237,60,32,122,156,158,17,225,48,53,103,117,46,94,91,200, 93,249,48,206,3,49,171,145,121,194,237,55,137,190,21,200,179,79,196,36, 24,114,252,203,99,187,180,235,139,174,154,64,206,219,5,87,11,209,203,254, 149,196,110 }; 62 | const uint8_t master61[] = { 225,41,74,127,96,108,234,255,19,129,178,139,43,244,113,146,94,129,129,151, 162,53,237,55,166,238,103,141,215,190,234,142,213,53,110,62,155,188,217, 187,39,234,214,239,115,53,194,98,211,4,95,17,17,213,8,199,12,171,162,172, 211,68,203,177 }; 63 | const uint8_t master62[] = { 133,100,189,25,253,43,51,103,6,1,99,156,196,62,72,216,144,23,214,84,223, 186,74,6,188,98,149,157,80,31,35,94,34,126,251,237,93,139,167,89,214,81, 30,116,203,109,6,84,53,239,29,119,201,20,195,143,161,81,55,14,75,20,212, 97 }; 64 | const uint8_t master63[] = { 161,27,115,145,250,123,188,180,210,181,75,188,168,100,241,180,63,59,107, 97,45,130,179,244,244,236,131,108,31,3,180,168,187,141,72,135,252,234,134, 154,82,190,151,129,147,249,243,134,184,30,87,184,75,232,141,66,207,0,133, 53,15,51,67,212 }; 65 | const uint8_t master64[] = { 101,160,120,89,138,55,143,101,195,183,206,125,109,67,250,237,41,114,174, 138,159,155,195,117 }; 66 | const uint8_t master65[] = { 203,174,244,74,38,46,117,60,68,66,41,10,254,115,188,137,7,236,174,47,0, 232,136,195,236,252 }; 67 | const uint8_t master66[] = { 174,186,45,36,166,134,195,43,166,108,76,55,250,33,26,63,162,119,54,236, 8,157,86,182,27,219,22,69 }; 68 | const uint8_t master67[] = { 166,192,210,132,109,61,0,253,174,98,153,105,16,224,95,51,55,219,252,179, 121,165,155,99,244,45,8,209,93,236 }; 69 | const uint8_t master68[] = { 204,231,166,234,4,44,45,128,31,41,88,61,211,74,103,23,150,216,55,191,117, 53,89,91,74,66,252,197,212,133,212,87 }; 70 | const uint8_t master69[] = { 14,209,202,119,79,43,96,216,89,90,223,163,37,248,28,168,94,17,98,247,17, 185,97,234,177,223,176,120,25,214,233,206,114,2 }; 71 | const uint8_t master70[] = { 228,190,242,61,252,95,94,21,207,75,6,8,131,254,215,92,42,219,131,136,175, 104,39,182,228,41,222,90,10,244,185,41,37,218,121,93 }; 72 | const uint8_t master71[] = { 166,69,162,214,21,198,15,56,236,125,233,198,240,135,76,81,91,79,84,1,151, 70,106,223,201,230,201,85,175,88,16,17,242,217,28,161,121,104 }; 73 | const uint8_t master72[] = { 177,104,86,135,228,33,176,89,104,110,111,15,240,197,48,207,121,235,40,129, 155,136,152,158,126,197,96,109,51,46,229,188 }; 74 | const uint8_t master73[] = { 3,23,173,220,246,1,189,8,243,33,118,204,157,144,69,12,131,230,88,198,254, 195,123,145,195,41,146,9,216,80,53,70,229 }; 75 | const uint8_t master74[] = { 44,194,119,220,37,79,65,47,132,215,159,182,87,94,165,188,100,159,23,16, 79,138,45,148,198,248,85,193,15,89,153,15,205,155 }; 76 | const uint8_t master75[] = { 154,166,121,23,155,28,43,106,215,235,89,109,245,7,235,90,203,158,139,30, 231,114,154,54,77,144,168,145,106,95,22,156,170,239,203 }; 77 | const uint8_t master76[] = { 190,26,115,144,206,183,93,13,47,174,150,237,36,71,248,202,217,237,94,112, 20,124,86,38,227,106,118,45,150,138,15,193,212,3,29,191 }; 78 | const uint8_t master77[] = { 7,183,194,218,57,173,45,230,80,11,30,194,44,209,179,93,114,139,99,108,147, 162,179,112,71,75,0,103,22,19,7,95,53,119,159,190,194 }; 79 | const uint8_t master78[] = { 204,109,168,196,153,13,43,138,85,164,29,155,94,196,219,10,227,110,93,125, 87,162,76,166,208,155,42,103,221,84,37,225,223,42,203,34,195,213 }; 80 | const uint8_t master79[] = { 158,101,171,59,253,115,222,45,156,1,116,105,156,8,247,63,49,124,28,55,13, 187,10,135,14,253,36,182,199,93,191,102,169,159,37,250,172,88,227 }; 81 | -------------------------------------------------------------------------------- /compiler/avr-gcc-4.8/bits/c++config.h: -------------------------------------------------------------------------------- 1 | // Predefined symbols and macros -*- C++ -*- 2 | 3 | // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 4 | // 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 5 | // 6 | // This file is part of the GNU ISO C++ Library. This library is free 7 | // software; you can redistribute it and/or modify it under the 8 | // terms of the GNU General Public License as published by the 9 | // Free Software Foundation; either version 3, or (at your option) 10 | // any later version. 11 | 12 | // This library is distributed in the hope that it will be useful, 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | // GNU General Public License for more details. 16 | 17 | // Under Section 7 of GPL version 3, you are granted additional 18 | // permissions described in the GCC Runtime Library Exception, version 19 | // 3.1, as published by the Free Software Foundation. 20 | 21 | // You should have received a copy of the GNU General Public License and 22 | // a copy of the GCC Runtime Library Exception along with this program; 23 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 | // . 25 | 26 | /** @file bits/c++config.h 27 | * This is an internal header file, included by other library headers. 28 | * Do not attempt to use it directly. @headername{iosfwd} 29 | */ 30 | 31 | #ifndef _GLIBCXX_CXX_CONFIG_H 32 | #define _GLIBCXX_CXX_CONFIG_H 1 33 | 34 | // The current version of the C++ library in compressed ISO date format. 35 | #define __GLIBCXX__ 20120920 36 | 37 | // Macros for various attributes. 38 | // _GLIBCXX_PURE 39 | // _GLIBCXX_CONST 40 | // _GLIBCXX_NORETURN 41 | // _GLIBCXX_NOTHROW 42 | // _GLIBCXX_VISIBILITY 43 | #ifndef _GLIBCXX_PURE 44 | # define _GLIBCXX_PURE __attribute__ ((__pure__)) 45 | #endif 46 | 47 | #ifndef _GLIBCXX_CONST 48 | # define _GLIBCXX_CONST __attribute__ ((__const__)) 49 | #endif 50 | 51 | #ifndef _GLIBCXX_NORETURN 52 | # define _GLIBCXX_NORETURN __attribute__ ((__noreturn__)) 53 | #endif 54 | 55 | // See below for C++ 56 | #ifndef _GLIBCXX_NOTHROW 57 | # ifndef __cplusplus 58 | # define _GLIBCXX_NOTHROW __attribute__((__nothrow__)) 59 | # endif 60 | #endif 61 | 62 | // Macros for visibility attributes. 63 | // _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 64 | // _GLIBCXX_VISIBILITY 65 | # define _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 1 66 | 67 | #if _GLIBCXX_HAVE_ATTRIBUTE_VISIBILITY 68 | # define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V))) 69 | #else 70 | // If this is not supplied by the OS-specific or CPU-specific 71 | // headers included below, it will be defined to an empty default. 72 | # define _GLIBCXX_VISIBILITY(V) _GLIBCXX_PSEUDO_VISIBILITY(V) 73 | #endif 74 | 75 | // Macros for deprecated attributes. 76 | // _GLIBCXX_USE_DEPRECATED 77 | // _GLIBCXX_DEPRECATED 78 | #ifndef _GLIBCXX_USE_DEPRECATED 79 | # define _GLIBCXX_USE_DEPRECATED 1 80 | #endif 81 | 82 | #if defined(__DEPRECATED) && defined(__GXX_EXPERIMENTAL_CXX0X__) 83 | # define _GLIBCXX_DEPRECATED __attribute__ ((__deprecated__)) 84 | #else 85 | # define _GLIBCXX_DEPRECATED 86 | #endif 87 | 88 | #if __cplusplus 89 | 90 | // Macro for constexpr, to support in mixed 03/0x mode. 91 | #ifndef _GLIBCXX_CONSTEXPR 92 | # ifdef __GXX_EXPERIMENTAL_CXX0X__ 93 | # define _GLIBCXX_CONSTEXPR constexpr 94 | # define _GLIBCXX_USE_CONSTEXPR constexpr 95 | # else 96 | # define _GLIBCXX_CONSTEXPR 97 | # define _GLIBCXX_USE_CONSTEXPR const 98 | # endif 99 | #endif 100 | 101 | // Macro for noexcept, to support in mixed 03/0x mode. 102 | #ifndef _GLIBCXX_NOEXCEPT 103 | # ifdef __GXX_EXPERIMENTAL_CXX0X__ 104 | # define _GLIBCXX_NOEXCEPT noexcept 105 | # define _GLIBCXX_USE_NOEXCEPT noexcept 106 | # define _GLIBCXX_THROW(_EXC) 107 | # else 108 | # define _GLIBCXX_NOEXCEPT 109 | # define _GLIBCXX_USE_NOEXCEPT throw() 110 | # define _GLIBCXX_THROW(_EXC) throw(_EXC) 111 | # endif 112 | #endif 113 | 114 | #ifndef _GLIBCXX_NOTHROW 115 | # define _GLIBCXX_NOTHROW _GLIBCXX_USE_NOEXCEPT 116 | #endif 117 | 118 | // Macro for extern template, ie controling template linkage via use 119 | // of extern keyword on template declaration. As documented in the g++ 120 | // manual, it inhibits all implicit instantiations and is used 121 | // throughout the library to avoid multiple weak definitions for 122 | // required types that are already explicitly instantiated in the 123 | // library binary. This substantially reduces the binary size of 124 | // resulting executables. 125 | // Special case: _GLIBCXX_EXTERN_TEMPLATE == -1 disallows extern 126 | // templates only in basic_string, thus activating its debug-mode 127 | // checks even at -O0. 128 | # define _GLIBCXX_EXTERN_TEMPLATE 1 129 | 130 | /* 131 | Outline of libstdc++ namespaces. 132 | 133 | namespace std 134 | { 135 | namespace __debug { } 136 | namespace __parallel { } 137 | namespace __profile { } 138 | namespace __cxx1998 { } 139 | 140 | namespace __detail { } 141 | 142 | namespace rel_ops { } 143 | 144 | namespace tr1 145 | { 146 | namespace placeholders { } 147 | namespace regex_constants { } 148 | namespace __detail { } 149 | } 150 | 151 | namespace tr2 { } 152 | 153 | namespace decimal { } 154 | 155 | namespace chrono { } 156 | namespace placeholders { } 157 | namespace regex_constants { } 158 | namespace this_thread { } 159 | } 160 | 161 | namespace abi { } 162 | 163 | namespace __gnu_cxx 164 | { 165 | namespace __detail { } 166 | } 167 | 168 | For full details see: 169 | http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html 170 | */ 171 | namespace std 172 | { 173 | typedef __SIZE_TYPE__ size_t; 174 | typedef __PTRDIFF_TYPE__ ptrdiff_t; 175 | 176 | #ifdef __GXX_EXPERIMENTAL_CXX0X__ 177 | typedef decltype(nullptr) nullptr_t; 178 | #endif 179 | } 180 | 181 | 182 | // Defined if inline namespaces are used for versioning. 183 | # define _GLIBCXX_INLINE_VERSION 0 184 | 185 | // Inline namespace for symbol versioning. 186 | #if _GLIBCXX_INLINE_VERSION 187 | 188 | namespace std 189 | { 190 | inline namespace __7 { } 191 | 192 | namespace rel_ops { inline namespace __7 { } } 193 | 194 | namespace tr1 195 | { 196 | inline namespace __7 { } 197 | namespace placeholders { inline namespace __7 { } } 198 | namespace regex_constants { inline namespace __7 { } } 199 | namespace __detail { inline namespace __7 { } } 200 | } 201 | 202 | namespace tr2 203 | { inline namespace __7 { } } 204 | 205 | namespace decimal { inline namespace __7 { } } 206 | 207 | namespace chrono { inline namespace __7 { } } 208 | namespace placeholders { inline namespace __7 { } } 209 | namespace regex_constants { inline namespace __7 { } } 210 | namespace this_thread { inline namespace __7 { } } 211 | 212 | namespace __detail { inline namespace __7 { } } 213 | namespace __regex { inline namespace __7 { } } 214 | } 215 | 216 | namespace __gnu_cxx 217 | { 218 | inline namespace __7 { } 219 | namespace __detail { inline namespace __7 { } } 220 | } 221 | # define _GLIBCXX_BEGIN_NAMESPACE_VERSION namespace __7 { 222 | # define _GLIBCXX_END_NAMESPACE_VERSION } 223 | #else 224 | # define _GLIBCXX_BEGIN_NAMESPACE_VERSION 225 | # define _GLIBCXX_END_NAMESPACE_VERSION 226 | #endif 227 | 228 | 229 | // Inline namespaces for special modes: debug, parallel, profile. 230 | #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PARALLEL) \ 231 | || defined(_GLIBCXX_PROFILE) 232 | namespace std 233 | { 234 | // Non-inline namespace for components replaced by alternates in active mode. 235 | namespace __cxx1998 236 | { 237 | #if _GLIBCXX_INLINE_VERSION 238 | inline namespace __7 { } 239 | #endif 240 | } 241 | 242 | // Inline namespace for debug mode. 243 | # ifdef _GLIBCXX_DEBUG 244 | inline namespace __debug { } 245 | # endif 246 | 247 | // Inline namespaces for parallel mode. 248 | # ifdef _GLIBCXX_PARALLEL 249 | inline namespace __parallel { } 250 | # endif 251 | 252 | // Inline namespaces for profile mode 253 | # ifdef _GLIBCXX_PROFILE 254 | inline namespace __profile { } 255 | # endif 256 | } 257 | 258 | // Check for invalid usage and unsupported mixed-mode use. 259 | # if defined(_GLIBCXX_DEBUG) && defined(_GLIBCXX_PARALLEL) 260 | # error illegal use of multiple inlined namespaces 261 | # endif 262 | # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_DEBUG) 263 | # error illegal use of multiple inlined namespaces 264 | # endif 265 | # if defined(_GLIBCXX_PROFILE) && defined(_GLIBCXX_PARALLEL) 266 | # error illegal use of multiple inlined namespaces 267 | # endif 268 | 269 | // Check for invalid use due to lack for weak symbols. 270 | # if __NO_INLINE__ && !__GXX_WEAK__ 271 | # warning currently using inlined namespace mode which may fail \ 272 | without inlining due to lack of weak symbols 273 | # endif 274 | #endif 275 | 276 | // Macros for namespace scope. Either namespace std:: or the name 277 | // of some nested namespace within it corresponding to the active mode. 278 | // _GLIBCXX_STD_A 279 | // _GLIBCXX_STD_C 280 | // 281 | // Macros for opening/closing conditional namespaces. 282 | // _GLIBCXX_BEGIN_NAMESPACE_ALGO 283 | // _GLIBCXX_END_NAMESPACE_ALGO 284 | // _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 285 | // _GLIBCXX_END_NAMESPACE_CONTAINER 286 | #if defined(_GLIBCXX_DEBUG) || defined(_GLIBCXX_PROFILE) 287 | # define _GLIBCXX_STD_C __cxx1998 288 | # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER \ 289 | namespace _GLIBCXX_STD_C { _GLIBCXX_BEGIN_NAMESPACE_VERSION 290 | # define _GLIBCXX_END_NAMESPACE_CONTAINER \ 291 | } _GLIBCXX_END_NAMESPACE_VERSION 292 | # undef _GLIBCXX_EXTERN_TEMPLATE 293 | # define _GLIBCXX_EXTERN_TEMPLATE -1 294 | #endif 295 | 296 | #ifdef _GLIBCXX_PARALLEL 297 | # define _GLIBCXX_STD_A __cxx1998 298 | # define _GLIBCXX_BEGIN_NAMESPACE_ALGO \ 299 | namespace _GLIBCXX_STD_A { _GLIBCXX_BEGIN_NAMESPACE_VERSION 300 | # define _GLIBCXX_END_NAMESPACE_ALGO \ 301 | } _GLIBCXX_END_NAMESPACE_VERSION 302 | #endif 303 | 304 | #ifndef _GLIBCXX_STD_A 305 | # define _GLIBCXX_STD_A std 306 | #endif 307 | 308 | #ifndef _GLIBCXX_STD_C 309 | # define _GLIBCXX_STD_C std 310 | #endif 311 | 312 | #ifndef _GLIBCXX_BEGIN_NAMESPACE_ALGO 313 | # define _GLIBCXX_BEGIN_NAMESPACE_ALGO 314 | #endif 315 | 316 | #ifndef _GLIBCXX_END_NAMESPACE_ALGO 317 | # define _GLIBCXX_END_NAMESPACE_ALGO 318 | #endif 319 | 320 | #ifndef _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 321 | # define _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 322 | #endif 323 | 324 | #ifndef _GLIBCXX_END_NAMESPACE_CONTAINER 325 | # define _GLIBCXX_END_NAMESPACE_CONTAINER 326 | #endif 327 | 328 | // GLIBCXX_ABI Deprecated 329 | // Define if compatibility should be provided for -mlong-double-64. 330 | #undef _GLIBCXX_LONG_DOUBLE_COMPAT 331 | 332 | // Inline namespace for long double 128 mode. 333 | #if defined _GLIBCXX_LONG_DOUBLE_COMPAT && defined __LONG_DOUBLE_128__ 334 | namespace std 335 | { 336 | inline namespace __gnu_cxx_ldbl128 { } 337 | } 338 | # define _GLIBCXX_NAMESPACE_LDBL __gnu_cxx_ldbl128:: 339 | # define _GLIBCXX_BEGIN_NAMESPACE_LDBL namespace __gnu_cxx_ldbl128 { 340 | # define _GLIBCXX_END_NAMESPACE_LDBL } 341 | #else 342 | # define _GLIBCXX_NAMESPACE_LDBL 343 | # define _GLIBCXX_BEGIN_NAMESPACE_LDBL 344 | # define _GLIBCXX_END_NAMESPACE_LDBL 345 | #endif 346 | 347 | // Assert. 348 | #if !defined(_GLIBCXX_DEBUG) && !defined(_GLIBCXX_PARALLEL) 349 | # define __glibcxx_assert(_Condition) 350 | #else 351 | namespace std 352 | { 353 | // Avoid the use of assert, because we're trying to keep the 354 | // include out of the mix. 355 | inline void 356 | __replacement_assert(const char* __file, int __line, 357 | const char* __function, const char* __condition) 358 | { 359 | __builtin_printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line, 360 | __function, __condition); 361 | __builtin_abort(); 362 | } 363 | } 364 | #define __glibcxx_assert(_Condition) \ 365 | do \ 366 | { \ 367 | if (! (_Condition)) \ 368 | std::__replacement_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ 369 | #_Condition); \ 370 | } while (false) 371 | #endif 372 | 373 | // Macros for race detectors. 374 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and 375 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain 376 | // atomic (lock-free) synchronization to race detectors: 377 | // the race detector will infer a happens-before arc from the former to the 378 | // latter when they share the same argument pointer. 379 | // 380 | // The most frequent use case for these macros (and the only case in the 381 | // current implementation of the library) is atomic reference counting: 382 | // void _M_remove_reference() 383 | // { 384 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount); 385 | // if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0) 386 | // { 387 | // _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount); 388 | // _M_destroy(__a); 389 | // } 390 | // } 391 | // The annotations in this example tell the race detector that all memory 392 | // accesses occurred when the refcount was positive do not race with 393 | // memory accesses which occurred after the refcount became zero. 394 | #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE 395 | # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) 396 | #endif 397 | #ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER 398 | # define _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) 399 | #endif 400 | 401 | // Macros for C linkage: define extern "C" linkage only when using C++. 402 | # define _GLIBCXX_BEGIN_EXTERN_C extern "C" { 403 | # define _GLIBCXX_END_EXTERN_C } 404 | 405 | #else // !__cplusplus 406 | # define _GLIBCXX_BEGIN_EXTERN_C 407 | # define _GLIBCXX_END_EXTERN_C 408 | #endif 409 | 410 | 411 | // First includes. 412 | 413 | // Pick up any OS-specific definitions. 414 | //#include 415 | 416 | // Pick up any CPU-specific definitions. 417 | //#include 418 | 419 | // If platform uses neither visibility nor psuedo-visibility, 420 | // specify empty default for namespace annotation macros. 421 | #ifndef _GLIBCXX_PSEUDO_VISIBILITY 422 | # define _GLIBCXX_PSEUDO_VISIBILITY(V) 423 | #endif 424 | 425 | // Certain function definitions that are meant to be overridable from 426 | // user code are decorated with this macro. For some targets, this 427 | // macro causes these definitions to be weak. 428 | #ifndef _GLIBCXX_WEAK_DEFINITION 429 | # define _GLIBCXX_WEAK_DEFINITION 430 | #endif 431 | 432 | 433 | // The remainder of the prewritten config is automatic; all the 434 | // user hooks are listed above. 435 | 436 | // Create a boolean flag to be used to determine if --fast-math is set. 437 | #ifdef __FAST_MATH__ 438 | # define _GLIBCXX_FAST_MATH 1 439 | #else 440 | # define _GLIBCXX_FAST_MATH 0 441 | #endif 442 | 443 | // This marks string literals in header files to be extracted for eventual 444 | // translation. It is primarily used for messages in thrown exceptions; see 445 | // src/functexcept.cc. We use __N because the more traditional _N is used 446 | // for something else under certain OSes (see BADNAMES). 447 | #define __N(msgid) (msgid) 448 | 449 | // For example, is known to #define min and max as macros... 450 | #undef min 451 | #undef max 452 | 453 | #endif // _GLIBCXX_CXX_CONFIG_H 454 | -------------------------------------------------------------------------------- /chaskey.js: -------------------------------------------------------------------------------- 1 | /* chaskey.js - a JS implementation of Chaskey algorithm in MAC and CBC modes 2 | * Chaskey algorithm invented by Nicky Mouha http://mouha.be/chaskey/ 3 | * 4 | * Copyright (C) 2017 Eugene Hutorny 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | 27 | /** 28 | * creates a new block, 32x4 bits, copies content from a, if compatible 29 | */ 30 | function block32x4(a) { 31 | var N = 4; 32 | this.v = a ? Uint32Array.from(a) : new Uint32Array(N); 33 | this.xor = function(blk) { 34 | for(var i in this.v) { this.v[i] ^= (blk.v||blk)[i]; } 35 | } 36 | this.xor_bytes = function(blk, size) { 37 | var v = new Uint8Array(this.v.buffer); 38 | var b = blk.v 39 | ? new Uint8Array(blk.v.buffer, blk.v.byteOffset) 40 | : new Uint8Array(blk.buffer, blk.byteOffset); 41 | for(var i = 0; i rounds 66 | * of transformations 67 | */ 68 | function ChaskeyCipher(block, count) { 69 | block.call(this); 70 | var N = count; 71 | this.block_t = block; 72 | function ror(val, n) { 73 | return (val << (32-n)) | (val >>> n); 74 | } 75 | 76 | function rol(val, n) { 77 | return (val >>> (32-n)) | (val << n); 78 | } 79 | this.round = function() { 80 | var v = this.block(); 81 | v[0] += v[1]; 82 | v[1] = rol(v[1], 5); 83 | v[1] ^= v[0]; 84 | v[0] = rol(v[0],16); 85 | v[2] += v[3]; 86 | v[3] = rol(v[3], 8); 87 | v[3] ^= v[2]; 88 | v[0] += v[3]; 89 | v[3] = rol(v[3],13); 90 | v[3] ^= v[0]; 91 | v[2] += v[1]; 92 | v[1] = rol(v[1], 7); 93 | v[1] ^= v[2]; 94 | v[2] = rol(v[2],16); 95 | } 96 | 97 | this.dnour = function(v) { 98 | //var v = this.block(); 99 | v[2] = ror(v[2],16); 100 | v[1] ^= v[2]; 101 | v[1] = ror(v[1], 7); 102 | v[2] -= v[1]; 103 | v[3] ^= v[0]; 104 | v[3] = ror(v[3],13); 105 | v[0] -= v[3]; 106 | v[3] ^= v[2]; 107 | v[3] = ror(v[3], 8); 108 | v[2] -= v[3]; 109 | v[0] = ror(v[0],16); 110 | v[1] ^= v[0]; 111 | v[1] = ror(v[1], 5); 112 | v[0] -= v[1]; 113 | } 114 | this.permute = function() { 115 | for(var i = N; i--; ) { 116 | this.round(); 117 | } 118 | } 119 | this.etumrep = function(v) { 120 | for(var i = N; i--; ) { 121 | this.dnour(v); 122 | } 123 | } 124 | this.derive = function(i) { 125 | i = i.v || i; 126 | return new this.block_t([ 127 | (i[0] << 1) ^((i[3] >> 31) & 0x87), /* >> for signed shift */ 128 | (i[1] << 1) | (i[0] >>> 31), 129 | (i[2] << 1) | (i[1] >>> 31), 130 | (i[3] << 1) | (i[2] >>> 31)]); 131 | } 132 | this.init = function(key) { 133 | this.assign(key); 134 | } 135 | this.clone = function() { 136 | return new ChaskeyCipher(this.block_t, N); 137 | } 138 | }; 139 | 140 | /** 141 | * Constructs a new block formatter, n specifies blok length in bytes 142 | */ 143 | function Formatter(n) { 144 | var N = n; 145 | var bytes = new Uint8Array(new ArrayBuffer(N)); 146 | var pos = 0; 147 | var len = 0; 148 | 149 | this.init = function(n) { 150 | N = n; 151 | bytes = new Uint8Array(new ArrayBuffer(N)); 152 | patch4IE(bytes); 153 | pos = 0; 154 | len = 0; 155 | } 156 | this.reset = function() { 157 | bytes.fill(0); 158 | pos = 0; 159 | len = 0; 160 | } 161 | function resize(l) { 162 | var res = new Uint8Array(new ArrayBuffer(l)); 163 | res.set(bytes); 164 | bytes = res; 165 | patch4IE(bytes); 166 | } 167 | 168 | /* https://github.com/feross/buffer/issues/60 */ 169 | function utf8ToBinaryString(str) { 170 | var escstr = encodeURIComponent(str); 171 | // replaces any uri escape sequence, such as %0A, with binary escape, such as 0x0A 172 | var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) { 173 | return String.fromCharCode('0x' + p1); 174 | }); 175 | 176 | return binstr; 177 | } 178 | 179 | function utf8ToBuffer(str) { 180 | var binstr = utf8ToBinaryString(str); 181 | var buf = new Uint8Array(binstr.length); 182 | Array.prototype.forEach.call(binstr, function (ch, i) { 183 | buf[i] = ch.charCodeAt(0); 184 | }); 185 | return buf; 186 | } 187 | 188 | 189 | this.append = function(message) { 190 | if( typeof(message) === typeof("") || message instanceof String) try { 191 | if( window.TextEncoder ) 192 | message = new TextEncoder("utf-8").encode(message); 193 | else 194 | message = utf8ToBuffer(message); 195 | } catch(e) { 196 | console.log(e); 197 | message = utf8ToBuffer(message); 198 | } 199 | if( !(message instanceof Uint8Array) ) 200 | throw Error("Message is not a byte string (Uint8Array or String)"); 201 | var l = len + message.length; 202 | if( l > bytes.length ) { 203 | resize(l + ((l % N) ? N - (l % N) : 0)); 204 | } 205 | bytes.set(message, len); 206 | len += message.length; 207 | } 208 | this.pad = function(firstbyte) { 209 | if( len && len == bytes.length ) return false; 210 | while(len < bytes.length ) { 211 | bytes[len++] = firstbyte; 212 | firstbyte = 0; 213 | } 214 | return true; 215 | } 216 | this.last = function() { 217 | return pos + N >= bytes.length; 218 | } 219 | this.block = function() { 220 | return new Uint32Array(bytes.buffer, pos, N/Uint32Array.BYTES_PER_ELEMENT); 221 | } 222 | this.next = function(data) { 223 | return (pos += N) < bytes.length; 224 | } 225 | this.move = function(data) { 226 | data && this.save(data); 227 | return (pos += N) < bytes.length; 228 | } 229 | this.save = function(data) { 230 | bytes.set(new Uint8Array(data.buffer), pos); 231 | } 232 | this.full = function() { 233 | return pos + N <= len; 234 | } 235 | this.bytes = function(l) { 236 | return Uint8Array.from(bytes.subarray(0,l||len)); 237 | } 238 | this.len = function() { 239 | return len; 240 | } 241 | } 242 | 243 | /** 244 | * Constructs a MAC crypto primitive 245 | */ 246 | function Mac(cipher, formatter) { 247 | var key = null; 248 | var subkey1 = null; 249 | var subkey2 = null; 250 | var buff = formatter || new Formatter(cipher.size); 251 | formatter && formatter.init(cipher.size); 252 | this.set = function(akey) { 253 | key = new cipher.block_t(akey); 254 | subkey1 = cipher.derive(key.block()); 255 | subkey2 = cipher.derive(subkey1.block()); 256 | cipher.init(key); 257 | } 258 | this.init = function () { 259 | cipher.init(key); 260 | } 261 | function encrypt(block) { 262 | cipher.xor(block); 263 | cipher.permute(); 264 | } 265 | this.sign = function(message) { 266 | if( key === null ) throw new Error("key is not set"); 267 | var finalkey = subkey1; 268 | cipher.init(key); 269 | buff.append(message); 270 | if ( buff.pad(1) ) finalkey = subkey2; 271 | do { 272 | if( buff.last() ) cipher.xor(finalkey); 273 | encrypt(buff.block()); 274 | } while(buff.next()); 275 | cipher.xor(finalkey); 276 | buff.reset(); 277 | return new Uint8Array(cipher.block().buffer); 278 | } 279 | } 280 | 281 | /** 282 | * Constructs a Cbc crypto primitive 283 | */ 284 | function Cbc(cipher, formatter) { 285 | var key = null; 286 | var buff = formatter || new Formatter(cipher.size); 287 | formatter && formatter.init(cipher.size); 288 | this.set = function(akey) { 289 | key = new cipher.block_t(akey); 290 | cipher.init(key); 291 | buff.reset(); 292 | } 293 | function encrypt(block) { 294 | cipher.xor(block); 295 | cipher.permute(); 296 | cipher.xor(key); 297 | } 298 | function decrypt(input) { 299 | var output = new cipher.block_t(input); 300 | output.xor(key); 301 | cipher.etumrep(output.block()); 302 | output.xor(cipher.block()); 303 | cipher.init(input); 304 | return output.block(); 305 | } 306 | /** initialize the cipher with initialization vector iv */ 307 | this.initIV = function(iv) { 308 | cipher.init(key); 309 | cipher.xor(new cipher.block_t(iv)); 310 | buff.reset(); 311 | } 312 | /** initialize the cipher with iv */ 313 | this.init = function(nonce) { 314 | if( key === null ) throw new Error("key is not set"); 315 | /* NIST Special Publication 800-38a 316 | * IV generation, recommended method number first. 317 | * Apply the forward cipher function, under the same key that is 318 | * used for the encryption of the plaintext, to a nonce */ 319 | cipher.init(cipher.derive(key)); 320 | buff.reset(); 321 | buff.append(nonce); 322 | do { 323 | encrypt(buff.block()); 324 | } while(buff.next()); 325 | buff.reset(); 326 | } 327 | this.encrypt = function(message, last) { 328 | if( key === null ) throw new Error("key is not set"); 329 | buff.append(message); 330 | if( last !== false ) buff.pad(0); 331 | if(! buff.full() ) return new Uint8Array(); 332 | do { 333 | encrypt(buff.block()); 334 | } while( buff.move(cipher.block()) ); 335 | return buff.bytes(); 336 | } 337 | this.decrypt = function(message, last) { 338 | if( key === null ) throw new Error("key is not set"); 339 | buff.append(message); 340 | if(! buff.full() ) return new Uint8Array(); 341 | while( buff.move(decrypt(buff.block()))); 342 | return buff.bytes(); 343 | } 344 | } 345 | 346 | /** 347 | * Constructs a Cloc crypto primitive 348 | */ 349 | function Cloc(Cipher, formatter) { 350 | var key = null; 351 | var ozp = false; 352 | var g1g2guard = false; 353 | var buff = formatter || new Formatter(Cipher.size); 354 | formatter && formatter.init(Cipher.size); 355 | var enc = Cipher; 356 | var tag = Cipher.clone(); 357 | 358 | function asHex(b) { 359 | b = Array.from(b.v || b); 360 | return '[' + b.map(function(i){ return i.toString(16); }).join(",") + ']'; 361 | } 362 | 363 | function cipher(input) { 364 | if( input ) tag.xor(input); 365 | tag.permute(); 366 | tag.xor(key); 367 | } 368 | 369 | function prf(tailsize, block) { 370 | block && enc.assign(block); 371 | tag.xor(key); 372 | cipher(enc); 373 | fix1(enc.block()); 374 | enc.xor(key) 375 | enc.permute(); 376 | tailsize == enc.size ? enc.xor(key) : enc.xor_bytes(key, tailsize); 377 | } 378 | 379 | /* CLOC-specific tweak function, */ 380 | /** f1(X) = (X[1, 3],X[2, 4],X[1, 2, 3],X[2, 3, 4]) */ 381 | function f1(b) { 382 | b[0] ^= b[2]; /* X[1, 3] */ 383 | var t = b[1]; 384 | b[1] ^= b[3]; /* X[2, 4] */ 385 | b[3] = b[2] ^ b[1]; /* X[2, 3, 4] */ 386 | b[2] = b[0] ^ t; /* X[1, 2, 3] */ 387 | } 388 | /** f2(X) = (X[2],X[3],X[4],X[1, 2]) */ 389 | function f2(b) { 390 | var t = b[0] ^ b[1]; 391 | b[0] = b[1]; /* X[2] */ 392 | b[1] = b[2]; /* X[2] */ 393 | b[2] = b[3]; /* X[4] */ 394 | b[3] = t; /* X[1, 2] */ 395 | } 396 | /** g1(X) = (X[3],X[4],X[1, 2],X[2, 3]) */ 397 | function g1(b) { 398 | var t = b[0]; 399 | b[0] = b[2]; /* X[3] */ 400 | b[2] = b[1] ^ t; /* X[1, 2] */ 401 | t = b[1]; 402 | b[1] = b[3]; /* X[4] */ 403 | b[3] = b[0] ^ t; /* X[2, 3] */ 404 | } 405 | /** g2(X) = (X[2],X[3],X[4],X[1, 2]) */ 406 | function g2(b) { f2(b); } 407 | /** h(X) = (X[1, 2],X[2, 3],X[3, 4],X[1, 2, 4]) */ 408 | function h(b) { 409 | b[0] ^= b[1]; /* X[1, 2] */ 410 | b[1] ^= b[2]; /* X[2, 3] */ 411 | b[2] ^= b[3]; /* X[3, 4] */ 412 | b[3] ^= b[0]; /* X[1, 2, 4] */ 413 | } 414 | function fix0(b) { 415 | var fixed = b[0] & 0x80000000; 416 | b[0] &= ~ 0x80000000; 417 | return !! fixed; 418 | } 419 | function fix1(b) { 420 | b[0] |= 0x80000000; 421 | } 422 | 423 | 424 | this.init = function() { 425 | ozp = false; 426 | g1g2guard = false; 427 | enc.init(key); 428 | buff.reset(); 429 | } 430 | 431 | this.set = function(akey) { 432 | key = new enc.block_t(akey); 433 | this.init(); 434 | } 435 | function update(block) { 436 | enc.xor(block); 437 | enc.permute(); 438 | enc.xor(key); 439 | } 440 | 441 | function process(block, tailsize, empty) { 442 | if( ! g1g2guard ) { 443 | if( empty ) g1(tag.block()); 444 | else g2(tag.block()); 445 | g1g2guard = true; 446 | } 447 | cipher(); 448 | tailsize == enc.size ? enc.xor(block) : enc.xor_bytes(block, tailsize); 449 | } 450 | /** processes associated data */ 451 | this.update = function(message) { 452 | if( key === null ) throw new Error("key is not set"); 453 | var fixed0 = false; 454 | buff.append(message); 455 | ozp = buff.pad(0x80); 456 | do { 457 | if( buff.last() ) fixed0 = fix0(enc.block()); 458 | update(buff.block()); 459 | if( fixed0 ) h(enc.block()); 460 | } while(buff.next()); 461 | buff.reset(); 462 | } 463 | 464 | /** applies a nonce */ 465 | this.nonce = function(nonce) { 466 | if( key === null ) throw new Error("key is not set"); 467 | buff.append(nonce); 468 | buff.pad(0x80); 469 | enc.xor(buff.block()); 470 | if( ozp ) f2(enc.block()); 471 | else f1(enc.block()); 472 | tag.assign(enc.block()); 473 | enc.permute(); 474 | enc.xor(key); 475 | buff.reset(); 476 | } 477 | 478 | /** encrypts a chunk of data */ 479 | this.encrypt = function(message, last) { 480 | if( key === null ) throw new Error("key is not set"); 481 | buff.append(message); 482 | last = ( last !== false ); 483 | var len = buff.len(); 484 | var tailsize = enc.size; 485 | if( last ) { 486 | tailsize = (buff.len() % enc.size) || enc.size; 487 | buff.pad(0); 488 | } 489 | while( buff.full() ) { 490 | var tail = buff.last() ? tailsize : enc.size; 491 | process(buff.block(), tail, last && len == 0); 492 | buff.save(enc.block()); 493 | prf(tail); 494 | buff.move(); 495 | } 496 | return buff.bytes(len); 497 | } 498 | 499 | /** decrypts a chunk of data */ 500 | this.decrypt = function(message, last) { 501 | if( key === null ) throw new Error("key is not set"); 502 | buff.append(message); 503 | last = ( last !== false ); 504 | var len = buff.len(); 505 | var tailsize = enc.size; 506 | if( last ) { 507 | tailsize = (buff.len() % enc.size) || enc.size; 508 | buff.pad(0); 509 | } 510 | while( buff.full() ) { 511 | var input = Uint32Array.from(buff.block()); 512 | var tail = buff.last() ? tailsize : enc.size; 513 | process(buff.block(), tail, last && len == 0); 514 | buff.move(enc.block()); 515 | prf(tail, input); 516 | } 517 | return buff.bytes(len); 518 | } 519 | 520 | /** returns digest (MAC) chunk of data */ 521 | this.mac = function() { 522 | return tag.raw(); 523 | } 524 | } 525 | 526 | /** ChaskeyCipher.Mac - a predefined primitive MAC using ChaskeyCipher */ 527 | ChaskeyCipher.Mac = function(count) { 528 | Mac.call(this, new ChaskeyCipher(block32x4, count||8)); 529 | } 530 | 531 | /** ChaskeyCipher.Cbc - a predefined primitive CBC using ChaskeyCipher */ 532 | ChaskeyCipher.Cbc = function(count) { 533 | Cbc.call(this, new ChaskeyCipher(block32x4, count||8)); 534 | } 535 | 536 | ChaskeyCipher.Cloc = function(count) { 537 | Cloc.call(this, new ChaskeyCipher(block32x4, count||8)); 538 | } 539 | 540 | /** patching IE */ 541 | if( ! Uint32Array.from ) { 542 | Uint32Array.from = function(src) { 543 | var dst = new Uint32Array(src.length||0); 544 | Array.prototype.every.call(dst, function(v,i) { dst[i] = src[i]; return true; }); 545 | return dst; 546 | } 547 | } 548 | if( ! Uint8Array.from ) { 549 | Uint8Array.from = function(src) { 550 | var dst = new Uint8Array(src.length||0); 551 | Array.prototype.every.call(dst, function(v,i) { dst[i] = src[i]; return true; }); 552 | return dst; 553 | 554 | } 555 | } 556 | if( ! Uint8Array.prototype.fill ) { 557 | Uint8Array.prototype.fill = function(val) { 558 | Array.prototype.every.call(this, function(v,i) { this[i] = val; return true; }); 559 | } 560 | } 561 | 562 | if( ! Array.from ) { 563 | Array.from = function(src) { 564 | var dst = new Array(src.length); 565 | dst.every(function(v,i) { dst[i] = src[i]; return true; }); 566 | return dst; 567 | } 568 | } 569 | 570 | function patch4IE(obj) { 571 | if( !obj.subarray ) 572 | obj.subarray = function(b,e) { 573 | return Uint8Array.from(Array.prototype.slice.call(this,b,e)); 574 | }; 575 | return obj; 576 | } 577 | 578 | /* patching IE */ 579 | -------------------------------------------------------------------------------- /tests/hosted/main.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017 Eugene Hutorny 2 | * 3 | * main.cpp - Command line interface for Chaskey Block Cipher 4 | * invented by Nicky Mouha http://mouha.be/chaskey/ 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "chaskey.h" 41 | #include "chaskey.hpp" 42 | #include "miculog.hpp" 43 | 44 | #ifdef WITH_AES128CLOC_TEST 45 | extern "C" { 46 | # include 47 | } 48 | #endif 49 | 50 | using namespace std; 51 | 52 | enum class operation { 53 | help, 54 | sign, 55 | verify, 56 | encrypt, 57 | decrypt, 58 | cloc, 59 | uncloc, 60 | test, 61 | bench, 62 | masters, 63 | }; 64 | 65 | enum exitcode { 66 | success, 67 | err_test, 68 | err_verify, 69 | bad_args, 70 | ioerror, 71 | exit_help, 72 | aborted 73 | }; 74 | 75 | struct options { 76 | const char* keyfile; 77 | const char* key; 78 | const char* textfile; 79 | const char* plaintext; 80 | const char* digest; 81 | const char* nonce; 82 | const char* iv; 83 | const char* ad; 84 | const char* adfile; 85 | const char* outfile; 86 | operation oper; 87 | bool hexout; 88 | bool hexkey; 89 | bool aes128cloc; 90 | bool tocerr; 91 | unsigned long param; 92 | }; 93 | 94 | static int verbosity = 1; 95 | 96 | class error : public exception { 97 | public: 98 | error(const string& message) noexcept : msg(message) {} 99 | const char* what() const noexcept { return msg.c_str(); } 100 | private: 101 | const string msg; 102 | }; 103 | 104 | void fillopts(int argc, char * const argv[], options& opts) { 105 | char c; 106 | while(-1 != (c = getopt(argc, argv, "edsm:cu:o:V:N:tT:b:k:K:i:I:X:a:A:hvqr2"))){ 107 | switch(c) { 108 | case 'e': opts.oper = operation::encrypt; break; 109 | case 'd': opts.oper = operation::decrypt; break; 110 | case 's': opts.oper = operation::sign; break; 111 | case 'm': opts.oper = operation::verify; opts.digest = optarg; break; 112 | case 't': opts.oper = operation::test; break; 113 | case 'c': opts.oper = operation::cloc; break; 114 | case 'u': opts.oper = operation::uncloc; opts.digest = optarg; break; 115 | case 'N': opts.nonce = optarg; break; 116 | case 'V': opts.iv = optarg; break; 117 | case 'k': opts.keyfile = optarg; opts.key = nullptr; break; 118 | case 'X': opts.key = optarg; opts.keyfile = nullptr; opts.hexkey = true; break; 119 | case 'K': opts.key = optarg; opts.keyfile = nullptr; opts.hexkey = false; break; 120 | case 'A': opts.ad = optarg; opts.adfile = nullptr; break; 121 | case 'a': opts.adfile = optarg; opts.ad = nullptr; break; 122 | case 'i': opts.textfile = optarg; opts.plaintext = nullptr; break; 123 | case 'I': opts.plaintext = optarg; opts.textfile = nullptr; break; 124 | case 'o': opts.outfile = optarg; break; 125 | case 'h': opts.hexout = true; break; 126 | case '2': opts.tocerr = true; break; 127 | case 'v': verbosity = 2; break; 128 | case 'q': verbosity = 0; break; 129 | # ifdef WITH_AES128CLOC_TEST 130 | case 'r': opts.aes128cloc = true; break; 131 | # endif 132 | case '?': opts.oper = operation::help; break; 133 | case 'T': opts.oper = operation::masters; opts.param = strtol(optarg,nullptr, 10); break; 134 | case 'b': opts.oper = operation::bench; opts.param = strtol(optarg,nullptr, 10); break; 135 | default: 136 | throw error(string("Unrecognized option '") + c + "'"); 137 | } 138 | } 139 | } 140 | 141 | static inline uint32_t hex(char c) { 142 | if( c == 0 ) return 0; 143 | if( c >= '0' && c <= '9' ) return c-'0'; 144 | if( c >= 'A' && c <= 'F' ) return c-'A' +0xA; 145 | if( c >= 'a' && c <= 'f' ) return c-'a' +0xa; 146 | throw error(string("Invalid hex character '") + c + "'"); 147 | } 148 | 149 | static inline uint32_t hex(const char * str) { 150 | return hex(str[1]) | (hex(str[0]) << 4); 151 | } 152 | 153 | using namespace crypto; 154 | using namespace chaskey; 155 | static constexpr block_t default_key { 156 | 0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210 157 | }; 158 | 159 | static ostream& operator<<(ostream& o, const block_t& k) { 160 | return o << '{' << hex << k[0] << ',' << k[1] << ',' << k[2] << ',' << k[3] << '}'; 161 | } 162 | 163 | static void hex2block(const char* str, block_t& key) { 164 | if( ! str ) 165 | throw error(string("Missing key, expected 32 hex digits")); 166 | if( 128 != (strlen(str) * 4) ) 167 | throw error(string("Invalid hex key :'") + str + "', expected 32 hex digits"); 168 | for(uint_fast8_t i = 0; i <16; ++i, str+=2) { 169 | key[i/4] |= hex(str) << (8*(i%4)); 170 | } 171 | } 172 | 173 | static uint_fast8_t hex2bytes(const char* str, uint8_t* key, uint_fast8_t len) { 174 | if( ! str ) 175 | throw error(string("Missing byte string")); 176 | uint_fast8_t i; 177 | for(i = 0; i < len && *str; ++i, str+=2) { 178 | key[i] = hex(str); 179 | if( ! str[1] ) break; 180 | } 181 | return i; 182 | } 183 | 184 | static bool getkeys(const options& opts, block_t& key, block_t& iv) { 185 | if( opts.keyfile ) { 186 | ifstream file(opts.keyfile, fstream::in | fstream::binary); 187 | if( ! file ) { 188 | throw error(string("Error accessing key file '") + opts.keyfile + "'"); 189 | } 190 | file.read(reinterpret_cast(&key[0]), sizeof(block_t)); 191 | if( ! file ) { 192 | throw error(string("Error reading key file '") + opts.keyfile + "'"); 193 | } 194 | return true; 195 | } 196 | for(auto& k : key) k = 0; 197 | if( opts.key ) { 198 | if( opts.hexkey ) { 199 | hex2block(opts.key, key); 200 | } else { 201 | if( 128 != (strlen(opts.key) * 8) ) 202 | throw error(string("Invalid key '") + opts.key + "', expected 16 characters"); 203 | for(int i = 0; i < 16; ++i) { 204 | key[i/4] |= static_cast(opts.key[i]) << ((i%4)*8); 205 | } 206 | } 207 | return true; 208 | } 209 | if( opts.iv ) { 210 | hex2block(opts.iv, iv); 211 | } 212 | 213 | for(int i=0; i<4; ++i) key[i] = default_key[i]; 214 | return false; 215 | } 216 | 217 | static istream& input(const options& opts) { 218 | static istringstream str; 219 | static fstream file; 220 | if(opts.plaintext) { 221 | str.str(opts.plaintext); 222 | return str; 223 | } 224 | if( opts.textfile ) { 225 | file.open(opts.textfile, fstream::in | fstream::binary ); 226 | if( ! file.good() ) 227 | cerr << "Error opening file '" << opts.textfile << "'" << endl; 228 | return file; 229 | } 230 | return cin; 231 | } 232 | 233 | static ostream& output(const options& opts) { 234 | static fstream file; 235 | if( opts.outfile ) { 236 | file.open(opts.outfile, fstream::out | fstream::binary ); 237 | if( ! file.good() ) 238 | cerr << "Error opening file '" << opts.outfile << "'" << endl; 239 | return file; 240 | } 241 | return cout; 242 | } 243 | 244 | 245 | static istream& adata(const options& opts) { 246 | static istringstream str; 247 | static fstream file; 248 | if(opts.ad) { 249 | str.str(opts.ad); 250 | return str; 251 | } 252 | if( opts.adfile) { 253 | file.open(opts.textfile, fstream::in | fstream::binary ); 254 | if( ! file.good() ) 255 | cerr << "Error opening file '" << opts.adfile << "'" << endl; 256 | return file; 257 | } 258 | str.str(""); 259 | return str; 260 | } 261 | 262 | 263 | struct hexwrapper { 264 | ostream& out; 265 | void write(const char* data, size_t len) { 266 | while(len--) { 267 | out << hex << setw(2) << setfill('0') << 268 | (static_cast(*data++) & 0xFF); 269 | } 270 | } 271 | }; 272 | 273 | static int sign(istream& in, const block_t& key, bool hexout, bool tocerr) { 274 | crypto::chaskey::Cipher8::Mac mac(key); 275 | while(in) { 276 | char plaintext[sizeof(block_t)]; 277 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount(); 278 | mac.update((const uint8_t*)plaintext, len, in.eof()); 279 | } 280 | if( tocerr ) { 281 | mac.write(hexwrapper{cerr}); 282 | cerr << endl; 283 | } else if( hexout ) { 284 | mac.write(hexwrapper{cout}); 285 | cout << endl; 286 | } else 287 | mac.write(cout); 288 | return success; 289 | } 290 | 291 | static int verify(istream& in, const block_t& key, const uint8_t* signature, uint_fast8_t len) { 292 | crypto::chaskey::Cipher8::Mac mac(key); 293 | while(in) { 294 | char plaintext[sizeof(block_t)]; 295 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount(); 296 | mac.update((const uint8_t*)plaintext, len, in.eof()); 297 | } 298 | return mac.verify(signature, len) ? success : err_verify; 299 | } 300 | 301 | static int encrypt(istream& in, ostream& out, 302 | const block_t& key, const char* nonce, const block_t& iv) { 303 | crypto::chaskey::Cipher8::Cbc cbc(key); 304 | if( nonce ) 305 | cbc.init(nonce, strlen(nonce)); 306 | else 307 | cbc.init(iv); 308 | while(in) { 309 | char plaintext[sizeof(block_t)]; 310 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount(); 311 | cbc.encrypt(out, (const uint8_t*)plaintext, len, in.peek() == EOF); 312 | } 313 | return success; 314 | } 315 | 316 | static int decrypt(istream& in, ostream& out, 317 | const block_t& key, const char* nonce, const block_t& iv) { 318 | crypto::chaskey::Cipher8::Cbc cbc(key); 319 | if( nonce ) 320 | cbc.init(nonce, strlen(nonce)); 321 | else 322 | cbc.init(iv); 323 | while(in) { 324 | char ciphertext[sizeof(block_t)]; 325 | size_t len = in.read(ciphertext,sizeof(ciphertext)).gcount(); 326 | cbc.decrypt(out, (const uint8_t*)ciphertext, len); 327 | } 328 | return success; 329 | } 330 | 331 | byte frominput[sizeof(block)] {}; 332 | 333 | #ifdef WITH_AES128CLOC_TEST 334 | 335 | static int aes128cloc(istream& in, istream& ad, ostream& out, 336 | const block_t& key, const char* nonce, bool hexout, const byte* mac) { 337 | ae_cxt cxt; 338 | ae_init(&cxt, (const byte*) key, sizeof(key)); 339 | if(ad) { 340 | stringstream sstr; 341 | sstr << ad.rdbuf(); 342 | const string& str = sstr.str(); 343 | process_ad(&cxt, reinterpret_cast(str.c_str()), str.length(), 344 | reinterpret_cast(nonce), strlen(nonce)); 345 | } else { 346 | process_ad(&cxt, reinterpret_cast(""), 0, 347 | reinterpret_cast(nonce), strlen(nonce)); 348 | } 349 | stringstream sstr; 350 | sstr << in.rdbuf(); 351 | const string& str = sstr.str(); 352 | std::vector cif(16 * ((str.length() + 15)/16)); 353 | std::vector tag(16); 354 | if( ! mac ) { 355 | ae_encrypt(&cxt, (byte*) str.c_str(), str.length(), cif.data(), tag.data(), tag.size(), ENC); 356 | out.write(reinterpret_cast(cif.data()), str.length()); 357 | if( hexout ) { 358 | hexwrapper{cout}.write(reinterpret_cast(tag.data()),tag.size()); 359 | cout << endl; 360 | } else { 361 | cout.write(reinterpret_cast(tag.data()),tag.size()); 362 | } 363 | return success; 364 | } else { 365 | auto len = str.length(); 366 | if( mac == frominput ) { 367 | len -= 16; 368 | mac = reinterpret_cast(str.c_str() + len); 369 | } 370 | ae_encrypt(&cxt, cif.data(), len, (byte*) str.c_str(), tag.data(), tag.size(), DEC); 371 | out.write(reinterpret_cast(cif.data()), cif.size()); 372 | return (memcmp(tag.data(), mac, 16) == 0) ? success : err_verify; 373 | } 374 | } 375 | 376 | #else 377 | static int aes128cloc(istream&, istream&, ostream&, 378 | const block_t&, const char*, bool, const byte* mac) throw(error) { 379 | throw error(string("aes128 is not available"); 380 | } 381 | #endif 382 | 383 | static int cloc(istream& in, istream& ad, ostream& out, 384 | const block_t& key, const char* nonce, bool hexout, bool tocerr) { 385 | crypto::chaskey::Cipher8::Cloc cloc(key); 386 | while(ad) { 387 | char plaintext[sizeof(block_t)]; 388 | size_t len = ad.read(plaintext,sizeof(plaintext)).gcount(); 389 | cloc.update((const uint8_t*)plaintext, len, ad.peek() == EOF); 390 | } 391 | if( nonce ) 392 | cloc.nonce((const uint8_t*)nonce, strlen(nonce)); 393 | while(in) { 394 | char plaintext[sizeof(block_t)]; 395 | size_t len = in.read(plaintext,sizeof(plaintext)).gcount(); 396 | cloc.encrypt(out, (const uint8_t*)plaintext, len, in.peek() == EOF); 397 | } 398 | if( tocerr ) { 399 | cloc.write(hexwrapper{cerr}); 400 | cerr << endl; 401 | } else if( hexout ) { 402 | cloc.write(hexwrapper{cout}); 403 | cout << endl; 404 | } else 405 | cloc.write(cout); 406 | return success; 407 | } 408 | 409 | static int uncloc(istream& in, istream& ad, ostream& out, const block_t& key, 410 | const char* nonce, const uint8_t* signature, uint_fast8_t len) { 411 | crypto::chaskey::Cipher8::Cloc cloc(key); 412 | while(ad) { 413 | char plaintext[sizeof(block_t)]; 414 | size_t len = ad.read(plaintext,sizeof(plaintext)).gcount(); 415 | cloc.update((const uint8_t*)plaintext, len, ad.peek() == EOF); 416 | } 417 | if( nonce ) 418 | cloc.nonce((const uint8_t*)nonce, strlen(nonce)); 419 | istream::pos_type end = (1ULL << 63) -1; 420 | if( signature == frominput ) { 421 | in.seekg(0, in.end); 422 | end = in.tellg(); 423 | end -= sizeof(frominput); 424 | in.seekg(end, in.beg); 425 | in.read((char*)frominput,sizeof(frominput)); 426 | in.seekg(0, in.beg); 427 | len = sizeof(frominput); 428 | } 429 | while(in && in.tellg() < end ) { 430 | char ciphertext[sizeof(block_t)]; 431 | size_t pos = in.tellg(); 432 | size_t size = ((pos + sizeof(block_t)) > end) 433 | ? end - in.tellg() 434 | : sizeof(block_t); 435 | size_t len = in.read(ciphertext,size).gcount(); 436 | cloc.decrypt(out, (const uint8_t*)ciphertext, len, in.peek() == EOF || size < sizeof(block_t)); 437 | } 438 | if( signature && len ) return cloc.verify(signature, len) ? success : err_verify; 439 | cloc.write(hexwrapper{cerr}); 440 | cerr << endl; 441 | return err_verify; 442 | } 443 | 444 | 445 | static int help() { 446 | cerr << "Usage: chaskey [options]" << endl 447 | << " is one of the following:" << endl 448 | << " -s : sign message" << endl 449 | << " -m : verify message signature " << endl 450 | << " -e : encrypt message" << endl 451 | << " -d : decrypt message" << endl 452 | << " -c : encrypt and sign message with CLOC" << endl 453 | << " -u : decrypt with CLOC and verify message signature " << endl 454 | << " -u . : decrypt with CLOC and verify message signature against last block in input" << endl 455 | << " -u - : decrypt with CLOC" << endl 456 | << " -t : self-test" << endl 457 | << " [options] are :" << endl 458 | << " -I : use message " << endl 459 | << " -i : read message from file " << endl 460 | << " -o : write output to file " << endl 461 | << " -K : set the key as byte string " << endl 462 | << " -X : set the key given as hexadecimal string " << endl 463 | << " -N : set the nonce as byte string " << endl 464 | << " -V : set the initialization vector as hexadecimal string " << endl 465 | << " -A : set the associated data as byte string " << endl 466 | << " -a : read associated data from file " << endl 467 | << " -k : read key from file " << endl 468 | << " -h : write signature in hexadecimal" << endl 469 | << " -2 : write hexadecimal signature to stderr" << endl 470 | << " -v : set verbose mode" << endl 471 | << " -q : set quite mode" << endl << endl 472 | << "For example: " << endl 473 | << "# chaskey -s -h -K secretkey16bytes -I Hello " << endl 474 | << "# chaskey -e -N nonce12bytes -K secretkey16bytes -i Hello.txt " << endl; 475 | return exit_help; 476 | } 477 | 478 | extern bool test(); 479 | extern const block_t& get_test_vector(unsigned); 480 | extern const uint8_t* get_test_message(); 481 | extern bool bench(unsigned long); 482 | 483 | __attribute__((weak)) 484 | bool test() { cerr << "Tests are not available" << endl; return false; } 485 | __attribute__((weak)) 486 | bool bench(unsigned) { cerr << "Benchmarking is not available" << endl; return false; } 487 | __attribute__((weak)) 488 | const block_t& get_test_vector(unsigned) { return default_key; } 489 | __attribute__((weak)) 490 | const uint8_t* get_test_message() { return (const uint8_t*)("Plain text message"); } 491 | 492 | unsigned long milliseconds() { 493 | return std::clock() / (CLOCKS_PER_SEC/1000); 494 | } 495 | 496 | const block_t iv { }; 497 | 498 | 499 | static void make_cbcmaster(int param) { 500 | crypto::chaskey::Chaskey8::Cbc cbc(get_test_vector(param)); 501 | cbc.init(iv); 502 | cbc.encrypt(cout, get_test_message(), param, true); 503 | } 504 | 505 | 506 | static void make_clocmaster(int i) { 507 | const uint8_t* msg = get_test_message(); 508 | crypto::chaskey::Chaskey8::Cloc cloc(get_test_vector(i)); 509 | cloc.update(msg + i%5, i, i >= 8); 510 | if( i < 8 ) 511 | cloc.update(msg + i%5, 16 - i, true); 512 | cloc.nonce(msg+i, i+3); 513 | cloc.encrypt(cout, msg, i+8, i >= 8); 514 | if( i < 8 ) 515 | cloc.encrypt(cout, msg+(i+8), i, true); 516 | cloc.write(cout); 517 | } 518 | 519 | static bool make_masters(int param) { 520 | if( param >= 80 ) return false; 521 | if( param >= 64 ) make_clocmaster(param-64); 522 | else make_cbcmaster(param); 523 | return true; 524 | } 525 | 526 | int main(int argc, char * const argv[]) { 527 | options opts = {}; 528 | block_t key, iv {}; 529 | opts.hexout = isatty(fileno(stdout)); 530 | try { 531 | if(argc < 1 && isatty(fileno(stdin)) ) 532 | cerr << "Processing stdin to stdout with a default key" << endl; 533 | else 534 | fillopts(argc, argv, opts); 535 | 536 | /* operations that require no key */ 537 | switch(opts.oper) { 538 | case operation::help: return ! help(); 539 | case operation::test: return ! test(); 540 | case operation::bench: return ! bench(opts.param); 541 | case operation::masters:return ! make_masters(opts.param); 542 | default:; 543 | } 544 | if( ! getkeys(opts, key, iv) ) { 545 | if( verbosity > 1 || (verbosity == 1 && isatty(fileno(stdin))) ) 546 | cerr << "Using default key " << key << endl; 547 | }; 548 | 549 | if( (opts.oper == operation::encrypt || opts.oper == operation::decrypt) && 550 | ! opts.nonce && ! opts.iv ) { 551 | if( verbosity > 1 || (verbosity == 1 && isatty(fileno(stdin))) ) 552 | cerr << "Using default iv " << iv << endl; 553 | } 554 | istream& in = input(opts); 555 | ostream& out = output(opts); 556 | if( ! in || ! out ) return ioerror; 557 | switch(opts.oper) { 558 | case operation::sign: 559 | return sign(in, key, opts.hexout, opts.tocerr); 560 | case operation::verify: { 561 | uint8_t digest[16] {}; 562 | auto len = hex2bytes(opts.digest, digest, sizeof(digest)); 563 | int res = verify(in, key, digest, len); 564 | if( verbosity > 1 && res == success ) 565 | cerr << "Verified" << endl; 566 | if( verbosity >= 1 && res != success ) 567 | cerr << "Not verified" << endl; 568 | return res; 569 | } 570 | case operation::encrypt: 571 | return encrypt(in, out, key, opts.nonce, iv); 572 | case operation::decrypt: 573 | return decrypt(in, out, key, opts.nonce, iv); 574 | case operation::cloc: { 575 | istream& ad ( adata(opts) ); 576 | return opts.aes128cloc 577 | ? aes128cloc(in, ad, out, key, opts.nonce, opts.hexout, nullptr) 578 | : cloc(in, ad, out, key, opts.nonce, opts.hexout, opts.tocerr); 579 | } 580 | case operation::uncloc: { 581 | istream& ad ( adata(opts) ); 582 | uint8_t digest[16] {}; 583 | uint8_t * mac = digest; 584 | uint_fast8_t len = 0; 585 | if( opts.digest ) { 586 | if( strcmp(opts.digest, ".") == 0 ) { 587 | mac = frominput; 588 | } else 589 | if( strcmp(opts.digest, "-") == 0 ) { 590 | mac = nullptr; 591 | } else 592 | len = hex2bytes(opts.digest, digest, sizeof(digest)); 593 | 594 | } 595 | if( ! ad ) return ioerror; 596 | int res = opts.aes128cloc 597 | ? aes128cloc(in, ad, out, key, opts.nonce, len, digest) 598 | : uncloc(in, ad, out, key, opts.nonce, mac, len); 599 | if( verbosity > 1 && res == success ) 600 | cerr << "Verified" << endl; 601 | if( verbosity >= 1 && res != success ) 602 | cerr << "Not verified" << endl; 603 | return res; 604 | } 605 | default:; 606 | return bad_args; 607 | }; 608 | if( isatty(fileno(stderr))) 609 | cerr << endl; 610 | } catch(const error& e) { 611 | if( verbosity >= 1 ) 612 | cerr << e.what() << endl; 613 | return bad_args; 614 | } catch(const exception& e) { 615 | if( verbosity >= 1 ) 616 | cerr << e.what() << endl; 617 | return ioerror; 618 | } catch(...) { 619 | if( verbosity >= 1 ) 620 | cerr << "Aborted" << endl; 621 | return aborted; 622 | } 623 | } 624 | 625 | void LogAppender::log(miculog::level lvl, const char* fmt, ...) noexcept { 626 | using typename miculog::level; 627 | FILE* file = stderr; 628 | switch( lvl ) { 629 | case level::fail: 630 | if( verbosity < 1 ) return; 631 | fprintf(file, "FAILED\t:"); 632 | break; 633 | case level::error: 634 | if( verbosity < 2 ) return; 635 | fprintf(file, "error\t:"); 636 | break; 637 | case level::warn: 638 | file = stdout; 639 | break; 640 | case level::info: 641 | file = stdout; 642 | if( verbosity < 1 ) return; 643 | case level::debug: 644 | break; 645 | default: 646 | return; 647 | } 648 | va_list args; 649 | va_start(args, fmt); 650 | vfprintf(file, fmt, args); 651 | va_end(args); 652 | } 653 | /* this substitues AES_encrypt to experiment with a reference 654 | * aes128cloc implementation 655 | * / 656 | extern "C" void AES_encrypt(const unsigned char *in, unsigned char *out, 657 | const AES_KEY *key) { 658 | using block_t = crypto::chaskey::Cipher<8>::block_t; 659 | crypto::chaskey::Cipher<8> & cipher = crypto::chaskey::Cipher8::cast(out); 660 | if( in != out ) 661 | cipher ^= *(const block_t*) in; 662 | cipher.permute(); 663 | cipher ^= *(const block_t*) key->rd_key; 664 | 665 | } 666 | //*/ 667 | 668 | -------------------------------------------------------------------------------- /tests/test.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2017 Eugene Hutorny 2 | * 3 | * test.cpp - self-testing facilities for a Chaskey Block Cipher algorithm 4 | * 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | * IN THE SOFTWARE. 23 | * 24 | * https://opensource.org/licenses/MIT 25 | */ 26 | 27 | #include "configuration.h" 28 | #include 29 | #include 30 | #include "chaskey.h" 31 | #include "chaskey.hpp" 32 | #include "miculog.hpp" 33 | #ifdef WITH_AES128CLOC_TEST 34 | extern "C" { 35 | # include "cloc.h" 36 | } 37 | #endif 38 | #ifdef WITH_CHACHA_TEST 39 | /* https://rweather.github.io/arduinolibs/classChaCha.html */ 40 | # include 41 | // chacha takes ~6200 bytes of ROM on AVR 42 | #endif 43 | namespace impl { 44 | #if defined(__AVR__) || defined(__MSP430__) 45 | typedef crypto::chaskey::Cipher8s Cipher8; 46 | #else 47 | typedef crypto::chaskey::Cipher8 Cipher8; 48 | #endif 49 | } 50 | struct memcpywrapper { 51 | uint8_t * data; 52 | size_t size; 53 | inline void write(const void* src, unsigned len) noexcept { 54 | memcpy(data, src, len); 55 | size += len; 56 | data += len; 57 | } 58 | }; 59 | 60 | namespace crypto { 61 | namespace test_compile { 62 | typedef uint32_t block_t[8]; 63 | struct Algorithm { 64 | static void permute(block_t&) {} 65 | static void etumrep(block_t&) {} 66 | }; 67 | Cbc,details::simple_formatter> TestCbc; 68 | Mac,details::simple_formatter> TestMac; 69 | 70 | void test() { 71 | uint8_t data[32]; 72 | TestCbc.init(data, sizeof(data)); 73 | TestCbc.encrypt(memcpywrapper{data}, data, sizeof(data), true); 74 | TestCbc.decrypt(memcpywrapper{data}, data, sizeof(data)); 75 | TestMac.update(data, sizeof(data), true); 76 | TestMac.write(memcpywrapper{data}); 77 | TestMac.verify((const block_t*)data); 78 | } 79 | } 80 | } 81 | 82 | extern void (*chaskey_cpp)(uint8_t *, uint32_t, const uint8_t *, const uint32_t, 83 | const uint32_t [4], const uint32_t [4], const uint32_t [4]); 84 | extern void (*subkeys_cpp)(uint32_t [4], uint32_t [4], const uint32_t [4]); 85 | 86 | using namespace crypto; 87 | using namespace chaskey; 88 | 89 | struct Test { 90 | static const uint8_t * const masters[79]; 91 | static const block_t vectors[64]; 92 | static const char plaintext[]; 93 | }; 94 | 95 | 96 | struct vector : chaskey::Cipher<8> { 97 | inline vector(const item_t* val) noexcept { 98 | memcpy(v,val,sizeof(v)); 99 | } 100 | using chaskey::Cipher<8>::dnour; 101 | using chaskey::Cipher<8>::round; 102 | inline void oround() noexcept { 103 | #define ROTL(x,b) (uint32_t)( ((x) >> (32 - (b))) | ( (x) << (b)) ) 104 | v[0] += v[1]; v[1]=ROTL(v[1], 5); v[1] ^= v[0]; v[0]=ROTL(v[0],16); 105 | v[2] += v[3]; v[3]=ROTL(v[3], 8); v[3] ^= v[2]; 106 | v[0] += v[3]; v[3]=ROTL(v[3],13); v[3] ^= v[0]; 107 | v[2] += v[1]; v[1]=ROTL(v[1], 7); v[1] ^= v[2]; v[2]=ROTL(v[2],16); 108 | } 109 | }; 110 | 111 | using miculog::level; 112 | 113 | 114 | struct Log : miculog::Log { 115 | static inline constexpr const char* fmt() noexcept { 116 | return sizeof(int) == sizeof(short) ? 117 | "%s{%08lX,%08lX,%08lX,%08lX}\n":"%s{%08X,%08X,%08X,%08X}\n"; 118 | } 119 | static const void block(level lvl, const char* msg, const block_t& b) noexcept { 120 | if( enabled(lvl) ) 121 | appender::log(lvl, fmt(), msg, b[0],b[1],b[2],b[3]); 122 | } 123 | static const void block(level lvl, const char* msg, const void* p) noexcept { 124 | const block_t& b = *static_cast(p); 125 | if( enabled(lvl) ) 126 | appender::log(lvl, fmt(), msg, b[0],b[1],b[2],b[3]); 127 | } 128 | } log; 129 | 130 | using details::rol; 131 | using details::ror; 132 | 133 | bool test_vectors() { 134 | uint8_t m[64]; 135 | uint8_t tag[16]; 136 | uint32_t k[4] = { 0x833D3433, 0x009F389F, 0x2398E64F, 0x417ACF39 }; 137 | uint32_t k1[4], k2[4]; 138 | int i; 139 | int ok = 1; 140 | uint32_t taglen = 16; 141 | 142 | /* key schedule */ 143 | subkeys(k1,k2,k); 144 | /* mac */ 145 | for (i = 0; i < 64; i++) { 146 | m[i] = i; 147 | 148 | chaskey_cpp(tag, taglen, m, i, k, k1, k2); 149 | details::simple_formatter buff; 150 | const block_t& result = buff.result(Test::vectors[i]); 151 | 152 | if (memcmp( tag, result, taglen )) { 153 | log.fail("test_vectors : length %d\n",i); 154 | log.block(level::error, "got : ", tag); 155 | log.block(level::error, "expected : ", result); 156 | ok = 0; 157 | } 158 | } 159 | 160 | return ok; 161 | } 162 | 163 | extern unsigned long milliseconds(); 164 | 165 | alignas(4) 166 | static uint8_t blank[32]; 167 | 168 | unsigned long bench_refmac(unsigned long count) { 169 | block_t subkey1{}, subkey2{}, k1{}; 170 | auto start = milliseconds(); 171 | while(count--) 172 | ::chaskey(blank, 16, blank, sizeof(blank), k1, subkey1, subkey2); 173 | return milliseconds() - start; 174 | } 175 | 176 | unsigned long bench_cppmac(unsigned long count) { 177 | block_t subkey1{}, subkey2{}, k1{}; 178 | auto start = milliseconds(); 179 | while(count--) 180 | chaskey_cpp(blank, 16, blank, sizeof(blank), k1, subkey1, subkey2); 181 | return milliseconds() - start; 182 | } 183 | 184 | 185 | struct blockassignwrapper { 186 | impl::Cipher8::Block& data; 187 | inline void write(const void* src, unsigned) noexcept { 188 | data = *reinterpret_cast(src); 189 | } 190 | }; 191 | unsigned long bench_mac(unsigned long count) { 192 | impl::Cipher8::Mac mac; 193 | const block_t& key{Test::vectors[0]}; 194 | impl::Cipher8::Block result; 195 | mac.set(key); 196 | auto start = milliseconds(); 197 | while(count--) { 198 | mac.init(); 199 | mac.update(blank,sizeof(blank),true); 200 | mac.write(blockassignwrapper{result}); 201 | } 202 | return milliseconds() - start; 203 | } 204 | 205 | #ifdef WITH_AES128CLOC_TEST 206 | unsigned long bench_aes128cloc(unsigned long count) { 207 | const block_t& key{Test::vectors[0]}; 208 | byte ad[32] {}, nonce[16] {}, pt[32]; 209 | 210 | ae_cxt ctx {}; 211 | ae_init(&ctx, reinterpret_cast(&key), sizeof(key)); 212 | auto start = milliseconds(); 213 | while(count--) { 214 | process_ad(&ctx, ad, sizeof(ad), nonce, sizeof(nonce)); 215 | ae_encrypt(&ctx, pt, sizeof(pt), ad, nonce, sizeof(nonce), ENC); 216 | } 217 | return milliseconds() - start; 218 | } 219 | #endif 220 | 221 | #ifdef WITH_CHACHA_TEST 222 | unsigned long bench_chacha(unsigned long count) { 223 | const block_t& key{Test::vectors[0]}; 224 | const block_t& iv{Test::vectors[1]}; 225 | 226 | uint8_t result[32]; 227 | ChaCha cbc(8); 228 | cbc.setKey((const uint8_t*)key, sizeof(key)); 229 | auto start = milliseconds(); 230 | while(count--) { 231 | cbc.setIV((const uint8_t*)iv, sizeof(iv)); 232 | cbc.encrypt(result,result,sizeof(result)); 233 | } 234 | return milliseconds() - start; 235 | } 236 | #endif 237 | 238 | 239 | static impl::Cipher8::Block result[2]; 240 | 241 | 242 | unsigned long bench_cloc(unsigned long count) { 243 | const block_t& key{Test::vectors[0]}; 244 | uint8_t ad[32] {}, nonce[16] {}, pt[32]; 245 | impl::Cipher8::Cloc cloc; 246 | cloc.set(key); 247 | cloc.init(); 248 | auto start = milliseconds(); 249 | while(count--) { 250 | cloc.update(ad, sizeof(ad), true); 251 | cloc.nonce(nonce, sizeof(nonce)); 252 | cloc.encrypt(blockassignwrapper{result[0]},pt,sizeof(pt),true); 253 | } 254 | return milliseconds() - start; 255 | } 256 | 257 | unsigned long bench_encrypt(unsigned long count) { 258 | const block_t& key{Test::vectors[0]}; 259 | const block_t& iv{Test::vectors[1]}; 260 | impl::Cipher8::Cbc cbc; 261 | cbc.set(key); 262 | auto start = milliseconds(); 263 | while(count--) { 264 | cbc.init(iv); 265 | cbc.encrypt(blockassignwrapper{result[0]},blank,sizeof(blank),true); 266 | } 267 | return milliseconds() - start; 268 | } 269 | 270 | unsigned long bench_decrypt(unsigned long count) { 271 | const block_t& key{Test::vectors[0]}; 272 | const block_t& iv{Test::vectors[1]}; 273 | impl::Cipher8::Cbc cbc; 274 | cbc.set(key); 275 | auto start = milliseconds(); 276 | while(count--) { 277 | cbc.init(iv); 278 | cbc.decrypt(blockassignwrapper{result[0]},blank,sizeof(blank)); 279 | } 280 | return milliseconds() - start; 281 | } 282 | 283 | 284 | bool bench(unsigned long count) { 285 | log.info("|%-12s|%-12s|%-12s|%-12s|%-12s|", 286 | " Ref MAC", " Cpp MAC", " MAC"," Encrypt", " Decrypt"); 287 | # ifdef WITH_AES128CLOC_TEST 288 | log.info("%-12s|"," aes128cloc"); 289 | # endif 290 | log.info("%-12s|"," CLOC"); 291 | # ifdef WITH_CHACHA_TEST 292 | log.info("%-12s|"," ChaCha"); 293 | # endif 294 | log.info("\n"); 295 | if( chaskey_cpp == &::chaskey ) 296 | log.warn("|%-12s", " -- N/A --"); 297 | else 298 | log.warn("|%8lu%4s", bench_refmac(count),""); 299 | log.warn("|%8lu%4s", bench_cppmac(count),""); 300 | log.warn("|%8lu%4s", bench_mac(count),""); 301 | log.warn("|%8lu%4s", bench_encrypt(count),""); 302 | log.warn("|%8lu%4s", bench_decrypt(count),""); 303 | # ifdef WITH_AES128CLOC_TEST 304 | log.warn("|%8lu%4s", bench_aes128cloc(count),""); 305 | # endif 306 | log.warn("|%8lu%4s", bench_cloc(count),""); 307 | # ifdef WITH_CHACHA_TEST 308 | log.warn("|%8lu%4s", bench_chacha(count),""); 309 | # endif 310 | 311 | log.warn("|\n"); 312 | return true; 313 | } 314 | 315 | /** 316 | * test rotation functions 317 | */ 318 | unsigned test_rolror(const block_t& v) { 319 | unsigned res = 0; 320 | for(auto i : {16,17,13,8,5} ) { 321 | if( (ror(v[0],i) == rol(v[0],i)) != (i==16) ) { 322 | log.fail( "test_rolror/ror!=rol : %d\n",i); 323 | log.error("ror(%08X,%d) :", ror(v[0],i)); 324 | log.error("rol(%08X,%d) :", rol(v[0],i)); 325 | ++res; 326 | } 327 | if( rol(ror(v[0],i),i) != v[0] ) { 328 | log.fail( "test_rolror/rol(ror) : %d\n",i); 329 | log.error("rol(ror(%08X,%d),%d) : %08X\n",v[0],i,i,rol(ror(v[0],i),i)); 330 | ++res; 331 | } 332 | } 333 | return res; 334 | } 335 | 336 | /** 337 | * test transformation 338 | */ 339 | unsigned test_transform(const block_t& v) { 340 | unsigned res = 0; 341 | vector o(v), r(v), m(v); 342 | o.oround(); 343 | r.round(); 344 | if( r != o ) { 345 | log.block(level::fail, "test_transform/round :", v); 346 | log.block(level::error,"expected :", o); 347 | log.block(level::error,"got :", r); 348 | ++res; 349 | } 350 | r.dnour(); 351 | if( r != m ) { 352 | log.block(level::fail, "test_transform/dnour :", v); 353 | log.block(level::error,"expected :", m); 354 | log.block(level::error,"got :", r); 355 | ++res; 356 | } 357 | r.permute(); 358 | r.etumrep(); 359 | if( r != m ) { 360 | log.block(level::fail, "test_transform/etumrep :", v); 361 | log.block(level::error,"expected :", m); 362 | log.block(level::error,"got :", r); 363 | ++res; 364 | } 365 | return res; 366 | } 367 | 368 | /** 369 | * test MAC reference chaskey head-to-head with crypto::chaskey implementations 370 | */ 371 | unsigned test_head2head(const block_t& v) { 372 | unsigned res = 0; 373 | # ifdef CHASKEY_HEAD2HEAD_TEST 374 | block_t subkey1, subkey2, k1, k2; 375 | subkeys(subkey1, subkey2, v); 376 | subkeys_cpp(k1,k2, v); 377 | if( memcmp(k1, subkey1, sizeof(k1)) != 0 ) { 378 | log.block(level::fail, "test_head2head/subkey1 :", subkey1); 379 | ++res; 380 | } 381 | if( memcmp(k2, subkey2, sizeof(k2)) != 0 ) { 382 | log.block(level::fail, "test_head2head/subkey2 :", subkey2); 383 | ++res; 384 | } 385 | block_t tag = {}; 386 | block_t mtag; 387 | for(auto i: {15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) { 388 | ::chaskey((uint8_t*)tag, sizeof(tag), (uint8_t*)Test::plaintext+(i&3), i, v, subkey1, subkey2); 389 | chaskey_cpp((uint8_t*)mtag, sizeof(mtag), (uint8_t*)Test::plaintext+(i&3), i, v, subkey1, subkey2); 390 | if( memcmp(tag,mtag, sizeof(mtag)) != 0 ) { 391 | log.block(level::fail, "test_head2head/mismatch :", tag); 392 | log.block(level::error,"expected :", mtag); 393 | log.error("message :'%.*s'\n", i, Test::plaintext+(i&3)); 394 | ++res; 395 | } 396 | } 397 | # endif 398 | return res; 399 | } 400 | 401 | /** 402 | * test MAC primitive with whole and partial messages 403 | */ 404 | unsigned test_mac(const block_t& v) { 405 | unsigned res = 0; 406 | block_t tag = {}; 407 | impl::Cipher8::Mac mac; 408 | block_t subkey1, subkey2; 409 | subkeys(subkey1, subkey2, v); 410 | 411 | mac.set(v); 412 | for(auto i: {15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) { 413 | uint8_t* msg = (uint8_t*)(Test::plaintext+(i&3)); 414 | chaskey_cpp((uint8_t*)&tag, sizeof(tag), msg, i, v, subkey1, subkey2); 415 | mac.init(); 416 | mac.update(msg, i, true); 417 | if( ! mac.verify(tag) ) { 418 | block_t got = {}; 419 | mac.write(memcpywrapper{(uint8_t*)&got, 0}); 420 | log.block(level::fail, "test_mac/verify :", got); 421 | log.block(level::error,"expected :", tag); 422 | log.error("message :'%.*s' %d bytes\n", i, msg, i); 423 | ++res; 424 | } 425 | } 426 | unsigned len = 0; 427 | uint8_t* msg = (uint8_t*)(Test::plaintext); 428 | mac.init(); 429 | for(auto i: {15, 17, 1, 14, 13}) { 430 | mac.update(msg, i, i == 13); 431 | msg += i; 432 | len += i; 433 | } 434 | chaskey_cpp((uint8_t*)&tag, sizeof(tag), (uint8_t*)(Test::plaintext), len, v, subkey1, subkey2); 435 | if( ! mac.verify(tag) ) { 436 | block_t got = {}; 437 | mac.write(memcpywrapper{(uint8_t*)&got, 0}); 438 | log.block(level::fail, "test_mac/update :", got); 439 | log.block(level::error,"expected :", tag); 440 | log.error("message :'%.*s'\n", len, Test::plaintext); 441 | ++res; 442 | } 443 | return res; 444 | } 445 | 446 | const block_t iv { }; 447 | /** 448 | * test CBC primitive encrypt/decrypt 449 | */ 450 | unsigned test_cbc(const block_t& v) { 451 | unsigned res = 0; 452 | impl::Cipher8::Cbc cbc; 453 | uint8_t tmp[64]; 454 | uint8_t plain[64]; 455 | cbc.set(v); 456 | for(auto i: {7, 8, 9, 15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) { 457 | cbc.init(iv); 458 | memcpywrapper wrp{tmp, 0}; 459 | cbc.encrypt(wrp, (const uint8_t*)Test::plaintext, i, true); 460 | cbc.init(iv); 461 | cbc.decrypt(memcpywrapper{plain,0}, tmp, wrp.size); 462 | if( strncmp(Test::plaintext,(const char*)plain, i) != 0) { 463 | log.fail( "test_cbc :\t'%.*s'\n", i, Test::plaintext); 464 | log.error("got :\t'%.*s'\n", i, plain); 465 | ++res; 466 | } 467 | } 468 | return res; 469 | } 470 | 471 | const block_t& get_test_vector(unsigned i) { 472 | if(i > 63) i = 0; 473 | return Test::vectors[i]; 474 | } 475 | const uint8_t* get_test_message() { 476 | return (const uint8_t*) Test::plaintext; 477 | } 478 | 479 | static unsigned test_clocmaster(int i) { 480 | uint8_t tmp[64]; 481 | unsigned res = 0; 482 | memcpywrapper cout{tmp,0}; 483 | const uint8_t* msg = get_test_message(); 484 | impl::Cipher8::Cloc cloc(get_test_vector(i)); 485 | cloc.update(msg + i%5, i, i >= 8); 486 | if( i < 8 ) 487 | cloc.update(msg + i%5, 16 - i, true); 488 | cloc.nonce(msg+i, i+3); 489 | cloc.encrypt(cout, msg, i+8, i >= 8); 490 | if( i < 8 ) 491 | cloc.encrypt(cout, msg + (i+8), i, true); 492 | int size = cout.size; 493 | cloc.write(cout); 494 | int len = i+8+(i<8?i:0); 495 | if( memcmp(tmp,Test::masters[i+63],cout.size) != 0 ) { 496 | log.fail("test_master/cloc :'%.*s'\n", len, msg); 497 | log.block(level::error,"got :", tmp+(cout.size-16)); 498 | log.block(level::error,"expected :", Test::masters[i+63]+(cout.size-16)); 499 | ++res; 500 | } 501 | cloc.init(); 502 | cloc.update(msg + i%5, i, i >= 8); 503 | if( i < 8 ) 504 | cloc.update(msg + i%5, 16 - i, true); 505 | cloc.nonce(msg+i, i+3); 506 | cout = {tmp, 0}; 507 | cloc.decrypt(cout, Test::masters[i+63], size, true); 508 | const block_t & tag{ *(const block_t*)(Test::masters[i+63]+size)}; 509 | if( ! cloc.verify(tag) ) { 510 | log.fail("test_master/verify :'%.*s'\n", len, msg); 511 | impl::Cipher8::Block got; 512 | cloc.write(blockassignwrapper{got}); 513 | log.block(level::error,"got :", got); 514 | log.block(level::error,"expected :", tag); 515 | ++res; 516 | } 517 | if( memcmp(tmp, msg, len) != 0 ) { 518 | log.fail("test_master/uncloc :'%.*s'\n", len, msg); 519 | log.error("got :\t'%.*s'\n", cout.size, tmp); 520 | ++res; 521 | } 522 | 523 | return res; 524 | } 525 | 526 | 527 | static unsigned test_cbcmaster(int i) { 528 | unsigned res = 0; 529 | uint8_t tmp[64]; 530 | impl::Cipher8::Cbc cbc; 531 | cbc.set(Test::vectors[i]); 532 | cbc.init(iv); 533 | memcpywrapper out{tmp,0}; 534 | cbc.encrypt(out, (const uint8_t*)Test::plaintext, i, true); 535 | if( memcmp(tmp,Test::masters[i-1],out.size) != 0 ) { 536 | log.fail("test_master/encrypt :'%.*s'\n", i, Test::plaintext); 537 | ++res; 538 | } 539 | cbc.init(iv); 540 | cbc.decrypt(memcpywrapper{tmp,0}, Test::masters[i-1], out.size); 541 | if( memcmp(tmp,Test::plaintext,i) != 0 ) { 542 | log.fail( "test_master/decrypt :'%.*s'\n", i, Test::plaintext); 543 | log.error("got :\t'%.*s'\n", i, tmp); 544 | ++res; 545 | } 546 | 547 | return res; 548 | } 549 | 550 | /** 551 | * test CBC adinst masters 552 | */ 553 | unsigned test_master(int N = 64) { //N added to prevent loop unrolling 554 | unsigned res = 0; 555 | for(int i = 1; i < N; ++i) 556 | res += test_cbcmaster(i); 557 | for(int i = N; i < 80; ++i) 558 | res += test_clocmaster(i-64); 559 | return res; 560 | } 561 | 562 | static char nonce[] = "16 bytes nonce"; 563 | 564 | /** 565 | * test CBC primitive encrypt/decrypt 566 | */ 567 | unsigned test_cloc(const block_t& v) { 568 | unsigned res = 0; 569 | impl::Cipher8::Cloc cloc; 570 | uint8_t tmp[64]; 571 | uint8_t plain[64]; 572 | cloc.set(v); 573 | for(auto i: {7, 8, 9, 15, 16, 17, 31, 32, 33, 47, 48, 49, 50}) { 574 | cloc.init(); 575 | cloc.update((const uint8_t*)(Test::plaintext + (i%4)), i, true); 576 | cloc.nonce((const uint8_t*)nonce,sizeof(nonce)); 577 | memcpywrapper wrp{tmp,0}; 578 | cloc.encrypt(wrp, (const uint8_t*)Test::plaintext + (i%6), i, true); 579 | cloc.init(); 580 | cloc.update((const uint8_t*)(Test::plaintext + (i%4)), i, true); 581 | cloc.nonce((const uint8_t*)nonce,sizeof(nonce)); 582 | cloc.decrypt(memcpywrapper{plain, 0}, tmp, i, true); 583 | if( strncmp(Test::plaintext + (i%6),(const char*)plain, i) != 0) { 584 | log.fail( "test_cloc :\t'%.*s'\n", i, Test::plaintext + (i%6)); 585 | log.error("got :\t'%.*s'\n", i, plain); 586 | ++res; 587 | } 588 | } 589 | return res; 590 | } 591 | 592 | /** 593 | * test CBC primitive encrypt/decrypt 594 | */ 595 | unsigned test_clocchunk() { 596 | unsigned adlen = 0, datalen = 0; 597 | impl::Cipher8::Cloc cloc; 598 | impl::Cipher8::Cloc verf; 599 | const block_t& v(Test::vectors[0]); 600 | uint8_t chunked[64]; 601 | uint8_t solid[64]; 602 | cloc.set(v); 603 | verf.set(v); 604 | 605 | uint8_t* ad = (uint8_t*)(Test::plaintext); 606 | for(auto i: {12, 5, 15, 1, 14, 13}) { 607 | cloc.update(ad, i, i == 13); 608 | ad += i; 609 | adlen += i; 610 | } 611 | cloc.nonce((uint8_t*)nonce, 7); 612 | uint8_t* msg = (uint8_t*)(Test::plaintext); 613 | memcpywrapper out{chunked,0}; 614 | for(auto i: {15, 17, 1, 14, 13}) { 615 | cloc.encrypt(out, msg, i, i == 13); 616 | msg += i; 617 | datalen += i; 618 | } 619 | memcpywrapper vrf{solid,0}; 620 | verf.update((uint8_t*)(Test::plaintext), adlen, true); 621 | verf.nonce((uint8_t*)nonce, 7); 622 | verf.encrypt(vrf, (uint8_t*)(Test::plaintext), datalen, true); 623 | if( memcmp(chunked, solid, vrf.size) ) { 624 | log.fail( "test_clocchunk\n"); 625 | return 1; 626 | } 627 | return 0; 628 | } 629 | 630 | bool test_debug() { 631 | return true; 632 | } 633 | 634 | 635 | bool test() { 636 | if( ! test_debug() ) return false; 637 | log.info("Running self-test %s\n", (chaskey_cpp == &::chaskey ? 638 | "without head-2-head" : "with head-2-head")); 639 | unsigned res = ! test_vectors(); 640 | for(const block_t& v : Test::vectors) { 641 | log.info("."); 642 | res += test_rolror(v); 643 | res += test_transform(v); 644 | res += test_cbc(v); 645 | res += test_cloc(v); 646 | } 647 | log.info("."); 648 | if( chaskey_cpp != &::chaskey ) 649 | res += test_head2head(Test::vectors[0]); 650 | log.info("."); 651 | res += test_mac(Test::vectors[0]); 652 | log.info("."); 653 | res += test_clocchunk(); 654 | log.info("."); 655 | res += test_master(); 656 | if( res ) 657 | log.warn("\n%d tests failed\n", res); 658 | else 659 | log.warn("\nAll tests pass\n"); 660 | return ! res; 661 | } 662 | 663 | const char Test::plaintext[] = "Plain text message of sufficient length. " 664 | "Plain text message of sufficient length"; 665 | 666 | 667 | const block_t Test::vectors[64] = 668 | { 669 | { 0x792E8FE5, 0x75CE87AA, 0x2D1450B5, 0x1191970B }, 670 | { 0x13A9307B, 0x50E62C89, 0x4577BD88, 0xC0BBDC18 }, 671 | { 0x55DF8922, 0x2C7FF577, 0x73809EF4, 0x4E5084C0 }, 672 | { 0x1BDBB264, 0xA07680D8, 0x8E5B2AB8, 0x20660413 }, 673 | { 0x30B2D171, 0xE38532FB, 0x16707C16, 0x73ED45F0 }, 674 | { 0xBC983D0C, 0x31B14064, 0x234CD7A2, 0x0C92BBF9 }, 675 | { 0x0DD0688A, 0xE131756C, 0x94C5E6DE, 0x84942131 }, 676 | { 0x7F670454, 0xF25B03E0, 0x19D68362, 0x9F4D24D8 }, 677 | { 0x09330F69, 0x62B5DCE0, 0xA4FBA462, 0xF20D3C12 }, 678 | { 0x89B3B1BE, 0x95B97392, 0xF8444ABF, 0x755DADFE }, 679 | { 0xAC5B9DAE, 0x6CF8C0AC, 0x56E7B945, 0xD7ECF8F0 }, 680 | { 0xD5B0DBEC, 0xC1692530, 0xD13B368A, 0xC0AE6A59 }, 681 | { 0xFC2C3391, 0x285C8CD5, 0x456508EE, 0xC789E206 }, 682 | { 0x29496F33, 0xAC62D558, 0xE0BAD605, 0xC5A538C6 }, 683 | { 0xBF668497, 0x275217A1, 0x40C17AD4, 0x2ED877C0 }, 684 | { 0x51B94DA4, 0xEFCC4DE8, 0x192412EA, 0xBBC170DD }, 685 | { 0x79271CA9, 0xD66A1C71, 0x81CA474E, 0x49831CAD }, 686 | { 0x048DA968, 0x4E25D096, 0x2D6CF897, 0xBC3959CA }, 687 | { 0x0C45D380, 0x2FD09996, 0x31F42F3B, 0x8F7FD0BF }, 688 | { 0xD8153472, 0x10C37B1E, 0xEEBDD61D, 0x7E3DB1EE }, 689 | { 0xFA4CA543, 0x0D75D71E, 0xAF61E0CC, 0x0D650C45 }, 690 | { 0x808B1BCA, 0x7E034DE0, 0x6C8B597F, 0x3FACA725 }, 691 | { 0xC7AFA441, 0x95A4EFED, 0xC9A9664E, 0xA2309431 }, 692 | { 0x36200641, 0x2F8C1F4A, 0x27F6A5DE, 0x469D29F9 }, 693 | { 0x37BA1E35, 0x43451A62, 0xE6865591, 0x19AF78EE }, 694 | { 0x86B4F697, 0x93A4F64F, 0xCBCBD086, 0xB476BB28 }, 695 | { 0xBE7D2AFA, 0xAC513DE7, 0xFC599337, 0x5EA03E3A }, 696 | { 0xC56D7F54, 0x3E286A58, 0x79675A22, 0x099C7599 }, 697 | { 0x3D0F08ED, 0xF32E3FDE, 0xBB8A1A8C, 0xC3A3FEC4 }, 698 | { 0x2EC171F8, 0x33698309, 0x78EFD172, 0xD764B98C }, 699 | { 0x5CECEEAC, 0xA174084C, 0x95C3A400, 0x98BEE220 }, 700 | { 0xBBDD0C2D, 0xFAB6FCD9, 0xDCCC080E, 0x9F04B41F }, 701 | { 0x60B3F7AF, 0x37EEE7C8, 0x836CFD98, 0x782CA060 }, 702 | { 0xDF44EA33, 0xB0B2C398, 0x0583CE6F, 0x846D823E }, 703 | { 0xC7E31175, 0x6DB4E34D, 0xDAD60CA1, 0xE95ABA60 }, 704 | { 0xE0DC6938, 0x84A0A7E3, 0xB7F695B5, 0xB46A010B }, 705 | { 0x1CEB6C66, 0x3535F274, 0x839DBC27, 0x80B4599C }, 706 | { 0xBBA106F4, 0xD49B697C, 0xB454B5D9, 0x2B69E58B }, 707 | { 0x5AD58A39, 0xDFD52844, 0x34973366, 0x8F467DDC }, 708 | { 0x67A67B1F, 0x3575ECB3, 0x1C71B19D, 0xA885C92B }, 709 | { 0xD5ABCC27, 0x9114EFF5, 0xA094340E, 0xA457374B }, 710 | { 0xB559DF49, 0xDEC9B2CF, 0x0F97FE2B, 0x5FA054D7 }, 711 | { 0x2ACA7229, 0x99FF1B77, 0x156D66E0, 0xF7A55486 }, 712 | { 0x565996FD, 0x8F988CEF, 0x27DC2CE2, 0x2F8AE186 }, 713 | { 0xBE473747, 0x2590827B, 0xDC852399, 0x2DE46519 }, 714 | { 0xF860AB7D, 0x00F48C88, 0x0ABFBB33, 0x91EA1838 }, 715 | { 0xDE15C7E1, 0x1D90EFF8, 0xABC70129, 0xD9B2F0B4 }, 716 | { 0xB3F0A2C3, 0x775539A7, 0x6CAA3BC1, 0xD5A6FC7E }, 717 | { 0x127C6E21, 0x6C07A459, 0xAD851388, 0x22E8BF5B }, 718 | { 0x08F3F132, 0x57B587E3, 0x087AD505, 0xFA070C27 }, 719 | { 0xA826E824, 0x3F851E6A, 0x9D1F2276, 0x7962AD37 }, 720 | { 0x14A6A13A, 0x469962FD, 0x914DB278, 0x3A9E8EC2 }, 721 | { 0xFE20DDF7, 0x06505229, 0xF9C9F394, 0x4361A98D }, 722 | { 0x1DE7A33C, 0x37F81C96, 0xD9B967BE, 0xC00FA4FA }, 723 | { 0x5FD01E9A, 0x9F2E486D, 0x93205409, 0x814D7CC2 }, 724 | { 0xE17F5CA5, 0x37D4BDD0, 0x1F408335, 0x43B6B603 }, 725 | { 0x817CEEAE, 0x796C9EC0, 0x1BB3DED7, 0xBAC7263B }, 726 | { 0xB7827E63, 0x0988FEA0, 0x3800BD91, 0xCF876B00 }, 727 | { 0xF0248D4B, 0xACA7BDC8, 0x739E30F3, 0xE0C469C2 }, 728 | { 0x67363EB6, 0xFAE8E047, 0xF0C1C8E5, 0x828CCD47 }, 729 | { 0x3DBD1D15, 0x05092D7B, 0x216FC6E3, 0x446860FB }, 730 | { 0xEBF39102, 0x8F4C1708, 0x519D2F36, 0xC67C5437 }, 731 | { 0x89A0D454, 0x9201A282, 0xEA1B1E50, 0x1771BEDC }, 732 | { 0x9047FAD7, 0x88136D8C, 0xA488286B, 0x7FE9352C } 733 | }; 734 | 735 | /* echo '' > tests/master.inc; for i in `seq 1 79`; do 736 | echo const uint8_t master$i[] = { `Debug/chaskey -T $i | file2c` }\; >> tests/master.inc; done; 737 | */ 738 | #include "master.inc" 739 | 740 | const uint8_t * const Test::masters[] = { 741 | master1, master2, master3, master4, master5, master6, master7, master8, 742 | master9 ,master10,master11,master12,master13,master14,master15,master16, 743 | master17,master18,master19,master20,master21,master22,master23,master24, 744 | master25,master26,master27,master28,master29,master30,master31,master32, 745 | master33,master34,master35,master36,master37,master38,master39,master40, 746 | master41,master42,master43,master44,master45,master46,master47,master48, 747 | master49,master50,master51,master52,master53,master54,master55,master56, 748 | master57,master58,master59,master60,master61,master62,master63,master64, 749 | master65,master66,master67,master68,master69,master70,master71,master72, 750 | master73,master74,master75,master76,master77,master78,master79 751 | }; 752 | -------------------------------------------------------------------------------- /tests/chaskey_test.js: -------------------------------------------------------------------------------- 1 | function ChaskeyTests() { 2 | 3 | function block2hex(blk) { 4 | if( ! (blk instanceof Uint32Array ) ) blk = new Uint32Array(blk.buffer||blk); 5 | return Array.prototype.map.call(blk, function(v) { 6 | return '0x'+('0000000' + v.toString(16)).slice(-8); 7 | }).join(','); 8 | } 9 | 10 | function bytes2hex(blk, dlm) { 11 | return Array.prototype.map.call(new Uint8Array(blk.buffer||blk), 12 | function(s){ return ('00' + s.toString(16)).slice(-2); }).join(dlm||''); 13 | } 14 | 15 | function logblock(msg, blk) { 16 | console.log(msg.toString() + block2hex(blk)); 17 | } 18 | 19 | 20 | this.loglevels = "fail,error,info,debug"; 21 | 22 | 23 | function compare(a,b,n) { 24 | return Array.prototype.every.call(a, function(v, i){ return v === b[i] || i >= n; }); 25 | } 26 | 27 | function string2bytes(str) { 28 | return Array.prototype.map.call(new Uint8Array(str.length),function(v,i) { return str.charCodeAt(i); }); 29 | } 30 | 31 | function bytes2string(str) { 32 | return Uint8Array.from(str.match(/.{1,2}/g).map(function(v) {return parseInt(v, 16); })); 33 | } 34 | 35 | /* https://github.com/feross/buffer/issues/60 */ 36 | function utf8ToBinaryString(str) { 37 | var escstr = encodeURIComponent(str); 38 | // replaces any uri escape sequence, such as %0A, with binary escape, such as 0x0A 39 | var binstr = escstr.replace(/%([0-9A-F]{2})/g, function(match, p1) { 40 | return String.fromCharCode('0x' + p1); 41 | }); 42 | 43 | return binstr; 44 | } 45 | 46 | function utf8ToBuffer(str) { 47 | var binstr = utf8ToBinaryString(str); 48 | var buf = new Uint8Array(binstr.length); 49 | Array.prototype.forEach.call(binstr, function (ch, i) { 50 | buf[i] = ch.charCodeAt(0); 51 | }); 52 | return buf; 53 | } 54 | 55 | function bufferToUtf8(arr) { 56 | return decodeURIComponent(escape(Array.prototype.map.call(arr, function(c) { return String.fromCharCode(c); }).join(''))); 57 | } 58 | 59 | function log(clas, msg) { 60 | var div = document.createElement('div'); 61 | div.setAttribute('class',clas); 62 | div.innerHTML = Array.prototype.map.call(msg, function(i) { 63 | return "" + i + ""; 64 | }).join(''); 65 | document.body.appendChild(div) 66 | } 67 | 68 | function generatePseudoRandomKey(func) { 69 | var key = new Uint8Array(16); 70 | Array.prototype.every.call(key, function(v,i) { 71 | key[i] = Math.random() * 256; 72 | return true; 73 | }); 74 | func(key); 75 | } 76 | 77 | 78 | function generateRandomCryptoKey(func) { 79 | window.crypto.subtle.generateKey({name:"AES-CBC",length:128},true, ["encrypt"]) 80 | .then(function(v) { 81 | window.crypto.subtle.exportKey("raw",v) 82 | .then(func);}).catch(function(e) { 83 | console.log('Fallback to pseaudo-random because "' + e.message + '"'); 84 | generatePseudoRandomKey(func); 85 | } ); 86 | } 87 | 88 | function generateRandomKey(func) { 89 | if( window.crypto && window.crypto.subtle ) 90 | try { 91 | return generateRandomCryptoKey(func); 92 | } catch(err) { 93 | console.log(err.message); 94 | } 95 | generatePseudoRandomKey(func); 96 | } 97 | 98 | this.demo = function() { 99 | this.ui = { 100 | mode : '#mode', 101 | key : '#key', 102 | data : '#data', 103 | nonce : '#nonce', 104 | message : '#message', 105 | ciphertext : '#ciphertext', 106 | encrypt : '#encrypt', 107 | decrypt : '#decrypt', 108 | sign : '#sign', 109 | format : '#format' 110 | }; 111 | var validmodes = { 112 | nonce : ['CBC','CLOC'], 113 | data : ['CLOC'], 114 | encrypt : ['CBC','CLOC'], 115 | decrypt : ['CBC','CLOC'], 116 | sign : ['MAC','CLOC'] 117 | } 118 | var ui = this.ui; 119 | Object.keys(ui).every(function(id) { 120 | ui[id] = document.querySelector(ui[id]); 121 | return true; 122 | }); 123 | var backend = this; 124 | backend.ui = ui; 125 | 126 | this.ui.encrypt.onclick = function() { 127 | backend.encrypt(ui.mode.value); 128 | } 129 | this.ui.decrypt.onclick = function() { 130 | backend.decrypt(ui.mode.value); 131 | } 132 | this.ui.sign.onclick = function() { 133 | backend.sign(ui.mode.value); 134 | } 135 | this.ui.format.onchange = function() { 136 | backend.formatchange(); 137 | } 138 | this.ui.ciphertext.onchange = function() { 139 | this.format = null; 140 | } 141 | this.ui.mode.onchange = function() { 142 | var value = this.value; 143 | Object.keys(validmodes).every(function(id){ 144 | ui[id].disabled = validmodes[id].indexOf(value) < 0; 145 | return true; 146 | }); 147 | } 148 | if( !this.ui.key.value ) { 149 | generateRandomKey(function(key) { 150 | backend.renderKey(key); 151 | }); 152 | } 153 | try { this.encoder = new TextEncoder('utf-8'); } 154 | catch(e) { 155 | console.log(e); 156 | this.encoder = { encode : utf8ToBuffer }; 157 | } 158 | try { this.decoder = new TextDecoder('utf-8'); } 159 | catch(e) { 160 | console.log(e); 161 | this.decoder = { decode : bufferToUtf8 }; 162 | } 163 | this.zero = this.decoder.decode(Uint8Array.from([0])) 164 | } 165 | 166 | this.renderKey = function(key) { 167 | this.ui.key.value = bytes2hex(key,'').toUpperCase(); 168 | } 169 | 170 | function validByte(v,s) { 171 | if (v>=0 && v<=255) return v; 172 | throw new Error('Invalid key digit:' + s); 173 | } 174 | function validInt(v,s) { 175 | if (v>=0 && v<=0xFFFFFFFF) return v; 176 | throw new Error('Invalid key digit:' + s); 177 | } 178 | 179 | this.readKey = function() { 180 | var key = this.ui.key.value === '' ? [] : this.ui.key.value.split(','); 181 | if( key.length == 1 ) key = key[0].match(/.{1,2}/g); 182 | if( [4,16].indexOf(key.length) == -1 ) { 183 | throw new Error('Invalid key length:' + key.length); 184 | } 185 | if( key.length == 16) { 186 | key = key.map(function(v) { return validByte(parseInt(v, 16), v); }); 187 | return new Uint32Array(Uint8Array.from(key).buffer); 188 | } 189 | if( key.length == 4) { 190 | key = key.map(function(v) { return validInt(parseInt(v, 16), v); }); 191 | return Uint32Array.from(key); 192 | } 193 | 194 | } 195 | 196 | this.encryptCBC = function(text) { 197 | var cbc = new ChaskeyCipher.Cbc(); 198 | cbc.set(this.readKey()); 199 | cbc.init(this.ui.nonce.value); 200 | return cbc.encrypt(this.encoder.encode(this.ui.message.value)); 201 | } 202 | 203 | this.encryptCLOC = function(text) { 204 | var cloc = new ChaskeyCipher.Cloc(); 205 | cloc.set(this.readKey()); 206 | cloc.update(this.ui.data.value); 207 | cloc.nonce(this.ui.nonce.value); 208 | return cloc.encrypt(text); 209 | } 210 | 211 | 212 | this.encrypt = function(mode) { 213 | try{ 214 | var text = this.encoder.encode(this.ui.message.value); 215 | var cif = mode === 'CBC' ? this.encryptCBC(text) : this.encryptCLOC(text); 216 | 217 | if( this.ui.format.value === 'base-64' ) 218 | this.ui.ciphertext.value = btoa(String.fromCharCode.apply(null, cif)); 219 | else 220 | this.ui.ciphertext.value = bytes2hex(cif); 221 | 222 | this.ui.ciphertext.format = this.ui.format.value; 223 | 224 | } catch(e) { 225 | this.error('ERROR:',e.message) 226 | } 227 | } 228 | 229 | this.decryptCBC = function(cif) { 230 | var cbc = new ChaskeyCipher.Cbc(); 231 | cbc.set(this.readKey()); 232 | cbc.init(this.ui.nonce.value); 233 | return cbc.decrypt(cif); 234 | } 235 | this.decryptCLOC = function(cif) { 236 | var cloc = new ChaskeyCipher.Cloc(); 237 | cloc.set(this.readKey()); 238 | cloc.update(this.ui.data.value); 239 | cloc.nonce(this.ui.nonce.value); 240 | return cloc.decrypt(cif); 241 | } 242 | 243 | this.decrypt = function(mode) { 244 | try{ 245 | 246 | var format = this.ui.ciphertext.format || this.ui.format.value; 247 | var cif; 248 | 249 | if( format === 'base-64' ) 250 | cif = Uint8Array.from(atob(this.ui.ciphertext.value).split('').map(function (c) { return c.charCodeAt(0); })); 251 | else 252 | cif = bytes2string(this.ui.ciphertext.value); 253 | var text = mode === 'CBC' ? this.decryptCBC(cif) : this.decryptCLOC(cif); 254 | this.ui.message.value = this.decoder.decode(text).split(this.zero)[0]; 255 | } catch(e) { 256 | this.error('ERROR:',e.message) 257 | } 258 | } 259 | 260 | this.signCLOC = function(text) { 261 | var mac = new ChaskeyCipher.Mac(); 262 | mac.set(this.readKey()); 263 | return mac.sign(this.encoder.encode(text)); 264 | } 265 | 266 | this.signMAC = function(text) { 267 | var mac = new ChaskeyCipher.Mac(); 268 | mac.set(this.readKey()); 269 | return mac.sign(this.encoder.encode(text)); 270 | } 271 | 272 | 273 | this.sign = function(mode) { 274 | try { 275 | var cif = mode === 'MAC' ? this.signMAC(this.ui.message.value) 276 | : this.signCLOC(this.ui.message.value); 277 | if( this.ui.format.value === 'base-64' ) 278 | this.ui.ciphertext.value = btoa(String.fromCharCode.apply(null, cif)); 279 | else 280 | this.ui.ciphertext.value = bytes2hex(cif); 281 | 282 | this.ui.ciphertext.format = this.ui.format.value; 283 | 284 | } catch(e) { 285 | this.error('ERROR:',e.message) 286 | } 287 | } 288 | 289 | 290 | this.formatchange = function() { 291 | 292 | } 293 | 294 | this.run = function() { 295 | this.info('INFO :', 'Starting chaskey tests'); 296 | if( this.test_MAC() ) 297 | this.info('PASS :', 'test_MAC'); 298 | else 299 | this.fail('FAIL :', 'test_MAC'); 300 | if( this.test_CBC() ) 301 | this.info('PASS :', 'test_CBC'); 302 | else 303 | this.fail('FAIL :', 'test_CBC'); 304 | if( this.test_CLOC() ) 305 | this.info('PASS :', 'test_CLOC'); 306 | else 307 | this.fail('FAIL :', 'test_CLOC'); 308 | } 309 | 310 | this.test_MAC = function() { 311 | var k = [ 0x833D3433, 0x009F389F, 0x2398E64F, 0x417ACF39 ]; 312 | var mac = new Mac(new ChaskeyCipher(block32x4, 8)); 313 | var m = new Uint8Array(64); 314 | var res = true; 315 | patch4IE(m); 316 | mac.set(k); 317 | 318 | for(var i=0; i < m.length; ++i) { 319 | m[i] = i; 320 | var tag = mac.sign(m.subarray(0,i)); 321 | if( ! compare(new Uint32Array(tag.buffer), this.vectors[i]) ) { 322 | this.error("error: test_MAC : length ",i); 323 | this.debug("got : ", block2hex(tag)); 324 | this.debug("expected : ", block2hex(this.vectors[i])); 325 | res = false; 326 | } 327 | } 328 | return res; 329 | } 330 | this.test_CBC = function() { 331 | var res = true; 332 | var cbc = new Cbc(new ChaskeyCipher(block32x4, 8)); 333 | var plaintext = string2bytes(this.plaintext); 334 | patch4IE(plaintext); 335 | for(var i = 1; i < 64; ++i) { 336 | cbc.set(this.vectors[i]); 337 | cbc.initIV([0,0,0,0]); 338 | var msg = plaintext.subarray(0,i); 339 | var cif = cbc.encrypt(msg); 340 | if( ! compare(cif, this.masters[i-1]) ) { 341 | this.error("error: test_CBC/encrypt: ",this.plaintext.substr(0,i)); 342 | this.debug("got : ", bytes2hex(cif)); 343 | this.debug("expected : ", bytes2hex(this.masters[i-1])); 344 | res = false; 345 | } 346 | cbc.initIV([0,0,0,0]); 347 | var txt = cbc.decrypt(cif); 348 | if( ! compare(txt, msg, i) ) { 349 | this.error("error: test_CBC/decrypt: ", this.plaintext.substr(0,i)); 350 | this.debug("got : ", bytes2hex(txt)); 351 | this.debug("expected : ", bytes2hex(msg)); 352 | res = false; 353 | } 354 | } 355 | return res; 356 | } 357 | var nonce = "16 bytes nonce"; 358 | thiz = this; 359 | 360 | function test_cloc() { 361 | var res = true; 362 | var cloc = new Cloc(new ChaskeyCipher(block32x4, 8)); 363 | var plaintext = string2bytes(thiz.plaintext); 364 | patch4IE(plaintext); 365 | var list = [7, 8, 9, 15, 16, 17, 31, 32, 33, 47, 48, 49, 50]; 366 | for(var j in list) { 367 | var i = list[j]; 368 | cloc.set(thiz.vectors[0]); 369 | cloc.update(plaintext.subarray(i%4,i+i%4), true); 370 | cloc.nonce(nonce); 371 | var msg = plaintext.subarray(i%6,i+i%6); 372 | var cif = cloc.encrypt(msg, true); 373 | cloc.init(); 374 | cloc.update(plaintext.subarray(i%4,i+i%4), true); 375 | cloc.nonce(nonce); 376 | var txt = cloc.decrypt(cif, true); 377 | if( ! compare(txt, msg, i) ) { 378 | thiz.error("error:test_CLOC/decrypt: ", thiz.plaintext.substr(0,i)); 379 | thiz.debug("got : ", bytes2hex(txt)); 380 | thiz.debug("expected : ", bytes2hex(msg)); 381 | res = false; 382 | } 383 | } 384 | return res; 385 | } 386 | 387 | function test_clocchunk() { 388 | var res = true; 389 | var cloc = new Cloc(new ChaskeyCipher(block32x4, 8)); 390 | var verf = new Cloc(new ChaskeyCipher(block32x4, 8)); 391 | var plaintext = string2bytes(thiz.plaintext); 392 | patch4IE(plaintext); 393 | var msglist = [15, 17, 1, 14, 13]; 394 | cloc.set(thiz.vectors[0]); 395 | cloc.update(plaintext.subarray(0,18)); 396 | cloc.nonce(nonce.substring(0,6)); 397 | var out; 398 | var datalen = 0; 399 | for(var j in msglist) { 400 | var i = msglist[j]; 401 | out = cloc.encrypt(plaintext.subarray(datalen, datalen+i), i == 13); 402 | datalen += i; 403 | } 404 | verf.set(thiz.vectors[0]); 405 | verf.update(plaintext.subarray(0,18)); 406 | verf.nonce(nonce.substring(0,6)); 407 | var vrf = verf.encrypt(plaintext.subarray(0,datalen), true); 408 | if( ! compare(out, vrf, datalen) ) { 409 | thiz.error("error:test_CLOC/chunk : ", thiz.plaintext.substr(0,datalen)); 410 | thiz.debug("got : ", bytes2hex(out)); 411 | thiz.debug("expected : ", bytes2hex(vrf)); 412 | return false; 413 | } 414 | return true; 415 | } 416 | 417 | function test_clocmaster() { 418 | var res = true; 419 | var cloc = new Cloc(new ChaskeyCipher(block32x4, 8)); 420 | var msg = string2bytes(thiz.plaintext); 421 | patch4IE(msg); 422 | for(var i = 0; i < 16; ++i) { 423 | cloc.set(thiz.vectors[i]); 424 | cloc.update(msg.subarray(i%5,i+i%5), i>=8); 425 | if( i < 8 ) 426 | cloc.update(msg.subarray(i%5,16-i+i%5), true); 427 | cloc.nonce(msg.subarray(i,i+i+3)); 428 | var out = cloc.encrypt(msg.subarray(0, i+8, i >= 8)); 429 | if( i < 8 ) 430 | out = cloc.encrypt(msg.subarray(i+8, i+i+8), true); 431 | var tmp = new Formatter(16); 432 | var len = i+8+(i<8?i:0); 433 | tmp.append(out); 434 | tmp.append(cloc.mac()); 435 | if( ! compare(tmp, thiz.masters[i+63], thiz.masters[i+63].length) ) { 436 | thiz.error("error:test_CLOC/master : ", thiz.plaintext.substr(0,len)); 437 | thiz.debug("got : ", bytes2hex(tmp)); 438 | thiz.debug("expected : ", thiz.masters[i+63]); 439 | res = false; 440 | } 441 | } 442 | return res; 443 | } 444 | 445 | this.test_CLOC = function() { 446 | return !!(test_clocmaster() & test_cloc() & test_clocchunk()); 447 | } 448 | 449 | 450 | this.fail = function() { 451 | console.log(Array.from(arguments).join('')); 452 | if( this.loglevels.indexOf('fail') >= 0 ) 453 | log('test-fail', arguments); 454 | } 455 | 456 | this.error = function() { 457 | console.log(Array.from(arguments).join('')); 458 | if( this.loglevels.indexOf('error') >= 0 ) 459 | log('test-error',arguments); 460 | } 461 | 462 | this.info = function() { 463 | console.log(Array.from(arguments).join('')); 464 | if( this.loglevels.indexOf('info') >= 0 ) 465 | log('test-info',arguments); 466 | } 467 | this.debug = function() { 468 | console.log(Array.from(arguments).join('')); 469 | if( this.loglevels.indexOf('debug') >= 0 ) 470 | log('test-debug',arguments); 471 | } 472 | 473 | this.plaintext = "Plain text message of sufficient length. Plain text message of sufficient length" 474 | 475 | this.vectors = [ 476 | [ 0x792E8FE5, 0x75CE87AA, 0x2D1450B5, 0x1191970B ], 477 | [ 0x13A9307B, 0x50E62C89, 0x4577BD88, 0xC0BBDC18 ], 478 | [ 0x55DF8922, 0x2C7FF577, 0x73809EF4, 0x4E5084C0 ], 479 | [ 0x1BDBB264, 0xA07680D8, 0x8E5B2AB8, 0x20660413 ], 480 | [ 0x30B2D171, 0xE38532FB, 0x16707C16, 0x73ED45F0 ], 481 | [ 0xBC983D0C, 0x31B14064, 0x234CD7A2, 0x0C92BBF9 ], 482 | [ 0x0DD0688A, 0xE131756C, 0x94C5E6DE, 0x84942131 ], 483 | [ 0x7F670454, 0xF25B03E0, 0x19D68362, 0x9F4D24D8 ], 484 | [ 0x09330F69, 0x62B5DCE0, 0xA4FBA462, 0xF20D3C12 ], 485 | [ 0x89B3B1BE, 0x95B97392, 0xF8444ABF, 0x755DADFE ], 486 | [ 0xAC5B9DAE, 0x6CF8C0AC, 0x56E7B945, 0xD7ECF8F0 ], 487 | [ 0xD5B0DBEC, 0xC1692530, 0xD13B368A, 0xC0AE6A59 ], 488 | [ 0xFC2C3391, 0x285C8CD5, 0x456508EE, 0xC789E206 ], 489 | [ 0x29496F33, 0xAC62D558, 0xE0BAD605, 0xC5A538C6 ], 490 | [ 0xBF668497, 0x275217A1, 0x40C17AD4, 0x2ED877C0 ], 491 | [ 0x51B94DA4, 0xEFCC4DE8, 0x192412EA, 0xBBC170DD ], 492 | [ 0x79271CA9, 0xD66A1C71, 0x81CA474E, 0x49831CAD ], 493 | [ 0x048DA968, 0x4E25D096, 0x2D6CF897, 0xBC3959CA ], 494 | [ 0x0C45D380, 0x2FD09996, 0x31F42F3B, 0x8F7FD0BF ], 495 | [ 0xD8153472, 0x10C37B1E, 0xEEBDD61D, 0x7E3DB1EE ], 496 | [ 0xFA4CA543, 0x0D75D71E, 0xAF61E0CC, 0x0D650C45 ], 497 | [ 0x808B1BCA, 0x7E034DE0, 0x6C8B597F, 0x3FACA725 ], 498 | [ 0xC7AFA441, 0x95A4EFED, 0xC9A9664E, 0xA2309431 ], 499 | [ 0x36200641, 0x2F8C1F4A, 0x27F6A5DE, 0x469D29F9 ], 500 | [ 0x37BA1E35, 0x43451A62, 0xE6865591, 0x19AF78EE ], 501 | [ 0x86B4F697, 0x93A4F64F, 0xCBCBD086, 0xB476BB28 ], 502 | [ 0xBE7D2AFA, 0xAC513DE7, 0xFC599337, 0x5EA03E3A ], 503 | [ 0xC56D7F54, 0x3E286A58, 0x79675A22, 0x099C7599 ], 504 | [ 0x3D0F08ED, 0xF32E3FDE, 0xBB8A1A8C, 0xC3A3FEC4 ], 505 | [ 0x2EC171F8, 0x33698309, 0x78EFD172, 0xD764B98C ], 506 | [ 0x5CECEEAC, 0xA174084C, 0x95C3A400, 0x98BEE220 ], 507 | [ 0xBBDD0C2D, 0xFAB6FCD9, 0xDCCC080E, 0x9F04B41F ], 508 | [ 0x60B3F7AF, 0x37EEE7C8, 0x836CFD98, 0x782CA060 ], 509 | [ 0xDF44EA33, 0xB0B2C398, 0x0583CE6F, 0x846D823E ], 510 | [ 0xC7E31175, 0x6DB4E34D, 0xDAD60CA1, 0xE95ABA60 ], 511 | [ 0xE0DC6938, 0x84A0A7E3, 0xB7F695B5, 0xB46A010B ], 512 | [ 0x1CEB6C66, 0x3535F274, 0x839DBC27, 0x80B4599C ], 513 | [ 0xBBA106F4, 0xD49B697C, 0xB454B5D9, 0x2B69E58B ], 514 | [ 0x5AD58A39, 0xDFD52844, 0x34973366, 0x8F467DDC ], 515 | [ 0x67A67B1F, 0x3575ECB3, 0x1C71B19D, 0xA885C92B ], 516 | [ 0xD5ABCC27, 0x9114EFF5, 0xA094340E, 0xA457374B ], 517 | [ 0xB559DF49, 0xDEC9B2CF, 0x0F97FE2B, 0x5FA054D7 ], 518 | [ 0x2ACA7229, 0x99FF1B77, 0x156D66E0, 0xF7A55486 ], 519 | [ 0x565996FD, 0x8F988CEF, 0x27DC2CE2, 0x2F8AE186 ], 520 | [ 0xBE473747, 0x2590827B, 0xDC852399, 0x2DE46519 ], 521 | [ 0xF860AB7D, 0x00F48C88, 0x0ABFBB33, 0x91EA1838 ], 522 | [ 0xDE15C7E1, 0x1D90EFF8, 0xABC70129, 0xD9B2F0B4 ], 523 | [ 0xB3F0A2C3, 0x775539A7, 0x6CAA3BC1, 0xD5A6FC7E ], 524 | [ 0x127C6E21, 0x6C07A459, 0xAD851388, 0x22E8BF5B ], 525 | [ 0x08F3F132, 0x57B587E3, 0x087AD505, 0xFA070C27 ], 526 | [ 0xA826E824, 0x3F851E6A, 0x9D1F2276, 0x7962AD37 ], 527 | [ 0x14A6A13A, 0x469962FD, 0x914DB278, 0x3A9E8EC2 ], 528 | [ 0xFE20DDF7, 0x06505229, 0xF9C9F394, 0x4361A98D ], 529 | [ 0x1DE7A33C, 0x37F81C96, 0xD9B967BE, 0xC00FA4FA ], 530 | [ 0x5FD01E9A, 0x9F2E486D, 0x93205409, 0x814D7CC2 ], 531 | [ 0xE17F5CA5, 0x37D4BDD0, 0x1F408335, 0x43B6B603 ], 532 | [ 0x817CEEAE, 0x796C9EC0, 0x1BB3DED7, 0xBAC7263B ], 533 | [ 0xB7827E63, 0x0988FEA0, 0x3800BD91, 0xCF876B00 ], 534 | [ 0xF0248D4B, 0xACA7BDC8, 0x739E30F3, 0xE0C469C2 ], 535 | [ 0x67363EB6, 0xFAE8E047, 0xF0C1C8E5, 0x828CCD47 ], 536 | [ 0x3DBD1D15, 0x05092D7B, 0x216FC6E3, 0x446860FB ], 537 | [ 0xEBF39102, 0x8F4C1708, 0x519D2F36, 0xC67C5437 ], 538 | [ 0x89A0D454, 0x9201A282, 0xEA1B1E50, 0x1771BEDC ], 539 | [ 0x9047FAD7, 0x88136D8C, 0xA488286B, 0x7FE9352C ] 540 | ]; 541 | this.masters = [ 542 | [ 222,202,68,203,71,185,154,219,88,87,129,165,229,233,20,84 ], 543 | [ 118,224,174,225,96,244,121,47,7,229,134,53,50,125,102,229 ], 544 | [ 181,138,189,126,50,202,139,119,242,229,175,10,166,232,171,135 ], 545 | [ 110,122,13,8,84,105,25,52,232,227,37,82,197,121,105,240 ], 546 | [ 152,133,195,170,129,159,115,98,75,234,31,71,144,111,76,123 ], 547 | [ 173,161,240,244,218,18,170,68,190,236,248,4,144,147,140,38 ], 548 | [ 208,231,42,190,67,254,150,98,203,135,73,122,146,167,113,229 ], 549 | [ 54,189,54,43,74,76,145,168,76,157,212,173,208,25,94,240 ], 550 | [ 31,72,238,18,104,238,139,142,45,85,187,193,182,105,38,5 ], 551 | [ 43,255,152,0,109,31,0,111,16,80,119,88,39,130,165,140 ], 552 | [ 94,178,192,27,86,56,148,42,195,180,12,94,61,200,52,150 ], 553 | [ 4,211,241,42,135,14,13,245,117,102,113,110,201,248,123,67 ], 554 | [ 237,114,121,205,231,88,56,34,182,190,62,123,243,252,2,236 ], 555 | [ 152,187,250,101,26,251,130,193,110,145,149,212,73,39,191,138 ], 556 | [ 8,12,29,139,151,244,30,9,11,87,218,149,152,92,22,246 ], 557 | [ 63,11,161,255,230,141,116,83,143,39,65,231,185,126,246,170 ], 558 | [ 128,245,151,12,111,204,71,170,139,246,19,222,188,68,227,186,60,117,238, 67,4,170,100,95,104,133,87,153,124,212,128,12 ], 559 | [ 20,77,65,9,13,109,229,60,0,3,186,56,190,90,48,93,186,122,200,16,202,13, 249,218,145,118,223,243,232,130,161,94 ], 560 | [ 4,57,187,192,5,81,173,237,228,166,182,157,23,47,153,229,109,161,81,4,202, 190,174,72,69,192,98,174,228,68,109,26 ], 561 | [ 247,71,207,142,146,27,182,0,67,12,235,174,107,70,38,165,186,169,21,187, 8,150,91,122,118,176,192,191,179,73,194,126 ], 562 | [ 243,51,36,207,216,59,71,0,130,237,118,32,61,223,238,214,136,65,188,52,68, 85,5,116,68,66,7,76,55,14,120,129 ], 563 | [ 132,15,0,170,117,62,62,232,76,31,204,103,92,224,225,162,224,244,164,189, 11,87,105,241,166,52,122,100,2,131,86,195 ], 564 | [ 14,90,143,161,121,159,73,147,26,248,88,201,32,241,198,177,88,147,168,10, 51,161,85,86,153,111,216,159,16,252,171,50 ], 565 | [ 46,137,166,99,10,9,161,19,201,26,190,248,124,221,138,23,18,119,130,83,66, 31,222,255,117,127,135,107,76,241,172,196 ], 566 | [ 65,96,98,247,42,85,245,104,121,123,23,102,33,130,213,150,181,251,20,191, 179,109,207,13,133,68,150,154,136,143,17,127 ], 567 | [ 238,77,117,246,217,33,56,85,205,216,1,163,42,189,112,85,104,65,145,65,200, 102,245,25,59,71,59,25,13,18,195,24 ], 568 | [ 175,155,175,187,29,60,129,58,151,108,248,196,181,96,156,242,113,215,42, 220,224,154,193,233,161,108,45,40,235,201,145,173 ], 569 | [ 143,58,180,175,39,226,132,151,224,46,144,191,193,230,87,90,46,125,106,225, 132,19,164,242,55,66,21,27,102,81,144,122 ], 570 | [ 119,60,95,2,38,129,245,99,74,20,55,199,56,162,238,64,44,89,38,8,255,225, 61,149,118,93,166,195,45,242,240,116 ], 571 | [ 1,140,255,176,19,225,59,182,85,220,132,29,98,57,1,59,33,163,1,83,60,3,232, 118,143,129,29,185,67,97,238,196 ], 572 | [ 24,236,188,144,157,4,152,167,29,125,37,66,220,168,245,72,50,191,158,70, 190,26,98,59,166,241,193,103,162,233,246,160 ], 573 | [ 89,121,164,54,147,181,38,167,34,213,245,92,174,126,14,74,144,110,146,95, 56,8,38,153,15,146,74,151,68,134,180,176 ], 574 | [ 73,13,241,83,220,5,32,25,68,34,116,111,234,221,64,94,20,55,93,242,83,11, 10,59,4,39,196,222,150,229,198,25,197,128,19,78,216,100,168,207,141,207, 175,29,120,24,159,29 ], 575 | [ 33,223,228,40,106,73,254,13,208,234,230,228,21,44,21,176,85,54,208,216, 187,55,175,198,63,31,60,191,244,84,76,25,115,157,106,166,73,145,102,46, 205,155,243,19,175,205,27,242 ], 576 | [ 2,229,11,152,59,105,209,14,144,148,195,182,137,119,145,89,143,185,212,8, 92,100,130,107,224,49,77,12,117,89,242,28,147,67,78,81,207,254,255,35,104, 132,93,28,169,163,249,17 ], 577 | [ 111,183,30,238,137,12,169,152,246,29,162,184,195,17,54,50,158,30,165,140, 231,255,180,250,127,237,85,80,133,88,228,246,97,52,13,120,114,104,192,7, 124,122,226,100,6,215,94,254 ], 578 | [ 14,133,180,190,194,136,108,116,80,17,2,6,113,129,33,134,150,121,255,152, 92,11,119,196,41,190,114,154,218,224,100,158,252,173,25,54,78,14,152,253, 29,91,51,49,138,133,86,195 ], 579 | [ 192,149,185,128,17,143,153,163,22,175,42,239,4,247,86,13,193,15,42,76,11, 22,17,17,110,117,125,251,35,30,218,133,190,140,152,74,106,130,88,87,68, 66,174,234,38,215,69,155 ], 580 | [ 179,112,80,9,233,55,89,134,49,254,119,181,114,238,13,90,158,193,50,2,158, 190,123,71,69,116,117,112,97,248,229,220,189,64,119,137,124,204,221,98, 198,109,77,186,158,215,209,17 ], 581 | [ 198,176,231,134,208,202,53,132,147,42,126,194,79,209,138,230,207,20,149, 59,47,229,137,27,126,46,234,18,240,100,194,183,201,199,175,190,166,133, 3,96,150,3,238,154,231,126,239,191 ], 582 | [ 233,227,197,48,11,194,2,96,106,121,24,213,29,135,235,72,143,178,52,214, 40,169,50,108,229,158,18,236,235,164,101,76,21,14,97,243,92,93,225,101, 7,203,68,115,114,79,86,210 ], 583 | [ 81,215,124,227,54,15,90,239,248,126,23,163,219,13,245,41,30,86,44,249,134, 52,221,127,240,30,141,123,249,8,126,221,226,156,188,235,158,84,165,56,158, 38,168,121,44,161,108,170 ], 584 | [ 215,156,195,2,145,102,237,9,196,188,163,145,199,35,228,179,28,23,23,249, 85,178,209,135,93,115,173,126,89,48,247,135,179,30,19,89,183,168,203,102, 34,125,207,137,33,84,227,20 ], 585 | [ 170,236,23,110,135,242,16,240,127,212,197,62,37,130,87,182,134,247,119, 78,61,134,173,159,214,68,203,93,143,247,247,101,163,234,79,216,76,234,227, 48,189,92,125,103,41,47,171,205 ], 586 | [ 118,70,104,186,35,9,3,77,66,135,235,65,99,242,94,169,113,10,14,103,68,106, 70,10,7,149,242,62,30,100,71,50,149,137,115,146,220,185,252,36,127,222, 232,223,134,45,200,14 ], 587 | [ 204,140,213,118,192,233,188,143,4,121,4,162,134,98,186,184,2,181,226,224, 108,234,26,82,94,22,96,49,161,202,40,239,201,13,29,73,250,175,210,176,50, 154,87,70,145,107,239,20 ], 588 | [ 160,68,57,205,169,228,3,107,118,58,91,200,14,166,79,44,219,181,213,27,86, 55,142,117,151,55,78,224,219,81,220,167,183,230,20,196,175,133,245,162, 22,86,144,66,85,214,187,235 ], 589 | [ 117,117,63,173,126,63,35,138,8,100,76,65,228,108,114,250,70,168,83,107, 133,12,248,18,209,232,62,247,111,94,200,8,174,49,96,108,36,74,30,114,188, 9,136,225,58,105,51,142 ], 590 | [ 157,1,60,58,10,176,179,199,24,164,77,239,147,96,254,187,168,93,172,8,209, 103,62,122,61,41,35,55,119,107,79,203,4,137,86,53,211,205,221,229,143,71, 131,69,42,4,155,104,19,174,125,223,242,28,65,211,195,41,197,208,9,137,2, 78 ], 591 | [ 161,212,83,134,155,103,237,212,88,188,177,162,36,16,53,8,52,218,66,239, 202,210,19,78,147,73,227,127,80,128,211,173,204,38,139,59,116,112,213,51, 177,127,54,250,142,13,149,250,174,240,91,131,2,217,59,89,21,210,246,95, 66,231,75,8 ], 592 | [ 83,56,156,44,197,77,160,143,93,249,83,46,110,207,34,249,155,249,53,121, 66,232,94,72,59,131,210,129,52,13,60,111,5,114,192,85,26,153,9,232,165, 43,102,200,94,173,217,165,181,77,236,252,53,247,89,255,9,16,240,150,230, 180,19,88 ], 593 | [ 6,9,131,74,104,2,18,36,129,24,75,80,246,121,209,152,247,9,20,55,148,155, 204,85,241,117,128,236,174,73,57,46,62,238,12,196,175,137,79,112,255,52, 218,205,195,135,94,141,213,213,170,144,62,45,91,199,225,185,22,145,155, 75,180,40 ], 594 | [ 124,27,241,23,212,79,223,87,129,214,34,161,230,240,168,245,116,197,84,67, 41,197,102,155,244,188,36,21,201,194,105,78,28,74,28,212,67,148,94,239, 182,211,130,4,133,147,2,20,91,226,222,159,41,63,206,184,198,205,148,138, 44,41,209,176 ], 595 | [ 84,104,143,97,29,117,50,48,5,241,116,142,186,158,229,99,95,186,245,237, 197,79,211,176,187,159,127,74,118,17,13,109,247,24,241,3,78,96,255,102, 180,70,228,123,173,59,151,163,110,9,111,199,107,146,179,188,137,61,103, 6,185,247,245,212 ], 596 | [ 118,110,183,199,103,39,114,241,127,81,119,239,215,127,28,236,115,64,116, 215,102,93,214,207,89,250,200,192,36,25,87,11,44,222,212,149,204,148,44, 255,188,58,157,25,127,24,153,122,92,89,37,133,216,96,141,185,45,115,99, 238,182,33,112,95 ], 597 | [ 196,213,190,214,69,184,227,220,28,132,237,60,124,167,236,17,174,150,24, 54,114,226,1,196,58,76,25,44,14,102,157,206,13,130,245,161,22,13,213,96, 116,154,246,227,241,139,102,219,182,152,20,131,26,167,38,159,239,236,210, 176,196,156,78,60 ], 598 | [ 101,147,225,111,103,140,133,149,241,30,23,60,65,248,83,131,194,253,65,198, 18,236,205,213,115,120,194,165,245,70,82,13,125,178,225,131,15,64,240,72, 16,112,128,30,154,57,15,92,25,130,55,222,255,112,188,112,253,246,189,26, 236,207,114,47 ], 599 | [ 199,161,228,120,85,125,46,243,141,87,89,70,88,113,253,104,68,254,5,237, 79,200,203,144,50,96,208,78,11,252,199,1,138,248,58,220,188,225,124,68, 197,210,249,31,167,107,86,202,222,124,145,187,104,231,99,155,255,235,59, 250,72,223,7,101 ], 600 | [ 41,194,24,135,196,138,136,5,61,201,81,96,150,96,116,201,105,26,31,123,131, 17,29,120,92,6,70,70,121,35,195,157,218,41,224,155,223,95,191,65,225,217, 172,68,235,37,46,203,73,169,206,26,45,8,20,42,248,142,0,204,80,183,202, 177 ], 601 | [ 99,45,35,44,153,237,60,32,122,156,158,17,225,48,53,103,117,46,94,91,200, 93,249,48,206,3,49,171,145,121,194,237,55,137,190,21,200,179,79,196,36, 24,114,252,203,99,187,180,235,139,174,154,64,206,219,5,87,11,209,203,254, 149,196,110 ], 602 | [ 225,41,74,127,96,108,234,255,19,129,178,139,43,244,113,146,94,129,129,151, 162,53,237,55,166,238,103,141,215,190,234,142,213,53,110,62,155,188,217, 187,39,234,214,239,115,53,194,98,211,4,95,17,17,213,8,199,12,171,162,172, 211,68,203,177 ], 603 | [ 133,100,189,25,253,43,51,103,6,1,99,156,196,62,72,216,144,23,214,84,223, 186,74,6,188,98,149,157,80,31,35,94,34,126,251,237,93,139,167,89,214,81, 30,116,203,109,6,84,53,239,29,119,201,20,195,143,161,81,55,14,75,20,212, 97 ], 604 | [ 161,27,115,145,250,123,188,180,210,181,75,188,168,100,241,180,63,59,107, 97,45,130,179,244,244,236,131,108,31,3,180,168,187,141,72,135,252,234,134, 154,82,190,151,129,147,249,243,134,184,30,87,184,75,232,141,66,207,0,133, 53,15,51,67,212 ], 605 | [ 101,160,120,89,138,55,143,101,149,250,239,152,122,121,84,36,214,3,120,13, 136,24,77,150 ], 606 | [ 203,174,244,74,38,46,117,60,68,66,72,177,59,67,128,132,145,155,75,155,158, 184,152,248,112,114 ], 607 | [ 174,186,45,36,166,134,195,43,166,108,76,55,245,5,165,205,26,117,120,118, 91,84,128,109,248,65,3,96 ], 608 | [ 166,192,210,132,109,61,0,253,174,98,153,105,16,224,193,146,94,252,231,155, 12,117,68,168,16,79,193,74,238,98 ], 609 | [ 204,231,166,234,4,44,45,128,31,41,88,61,211,74,103,23,115,20,240,79,191, 85,176,28,201,232,251,73,118,217,238,47 ], 610 | [ 14,209,202,119,79,43,96,216,89,90,223,163,37,248,28,168,129,187,100,114, 72,199,168,20,109,194,49,72,48,185,97,120,41,82 ], 611 | [ 228,190,242,61,252,95,94,21,207,75,6,8,131,254,215,92,34,180,100,2,59,79, 70,67,85,190,230,161,70,182,219,114,103,239,104,19 ], 612 | [ 166,69,162,214,21,198,15,56,236,125,233,198,240,135,76,81,80,9,126,200, 209,190,28,55,165,230,72,5,187,49,171,199,189,83,43,183,171,165 ], 613 | [ 177,104,86,135,228,33,176,89,104,110,111,15,240,197,48,207,123,81,89,55, 116,150,14,68,146,182,12,108,211,32,144,183 ], 614 | [ 3,23,173,220,246,1,189,8,243,33,118,204,157,144,69,12,155,20,149,55,254, 9,10,48,19,130,156,28,32,213,178,103,173 ], 615 | [ 44,194,119,220,37,79,65,47,132,215,159,182,87,94,165,188,26,73,227,116, 226,189,48,4,226,71,125,220,25,11,181,221,232,32 ], 616 | [ 154,166,121,23,155,28,43,106,215,235,89,109,245,7,235,90,161,140,15,100, 64,2,35,58,45,49,203,157,132,42,19,86,11,180,248 ], 617 | [ 190,26,115,144,206,183,93,13,47,174,150,237,36,71,248,202,42,23,154,31, 212,8,111,199,18,75,138,153,168,207,225,232,212,197,242,234 ], 618 | [ 7,183,194,218,57,173,45,230,80,11,30,194,44,209,179,93,113,191,126,147, 117,174,4,4,174,98,246,59,74,120,233,65,176,39,0,220,234 ], 619 | [ 204,109,168,196,153,13,43,138,85,164,29,155,94,196,219,10,1,0,204,253,87, 227,228,104,77,42,45,139,116,82,100,110,250,30,225,12,157,244 ], 620 | [ 158,101,171,59,253,115,222,45,156,1,116,105,156,8,247,63,131,52,177,40, 52,245,6,115,127,73,142,76,223,215,11,151,73,84,164,13,205,213,51 ] 621 | ]; 622 | } 623 | --------------------------------------------------------------------------------