diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4265b01
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+.vs/
+CMakeSettings.json
+out/
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..e0edb9d
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.15)
+project(bitpolymul VERSION 1.0.1)
+
+if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE Release)
+endif()
+
+include("cmake/buildOptions.cmake")
+
+add_subdirectory(bitpolymul)
+
+include("cmake/install.cmake")
\ No newline at end of file
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 082ba60..0000000
--- a/Makefile
+++ /dev/null
@@ -1,77 +0,0 @@
-CC= gcc
-CXX= g++
-LD= gcc
-
-CFLAGS= -O3 -funroll-loops -mavx2 -mpclmul -std=gnu99 -Wextra -Wall
-CXXFLAGS= -O3 -mavx2 -mpclmul -fno-exceptions -fno-rtti -nostdinc++ -Wextra -Wall
-INCPATH= -I/usr/local/include -I/opt/local/include -I/usr/include #-I../../nist-mq-submission/gf2-dev/
-LDFLAGS=
-LIBPATH= -L/usr/local/lib -L/opt/local/lib -L/usr/lib #-L../gf2-dev/
-LIBS= #-lm -lcrypto -lgf2x
-
-
-OBJ= bc.o bitpolymul.o encode.o butterfly_net.o gf2128_cantor_iso.o btfy.o trunc_btfy_tab.o gf264_cantor_iso.o trunc_btfy_tab_64.o
-EXE= bitpolymul-test #bc-test
-
-
-CSRC= $(wildcard *.cpp)
-
-
-ifdef DEBUG
- CFLAGS+= -D_DEBUG_
- CXXFLAGS+= -D_DEBUG_
-endif
-
-ifdef NO_SSE
- CFLAGS += -D_NO_SSE_
- CXXFLAGS += -D_NO_SSE_
-endif
-
-
-ifdef K
- CFLAGS += -DK=$(K)
- CXXFLAGS += -DK=$(K)
-endif
-
-
-ifdef AVX2
- CFLAGS += -mavx2 -D_USE_AVX2_
- CXXFLAGS += -mavx2 -D_USE_AVX2_
-endif
-
-ifdef AVX
- CFLAGS += -mavx -D_USE_AVX_
- CXXFLAGS += -mavx -D_USE_AVX_
-endif
-
-ifdef GPROF
- CFLAGS += -pg
- CXXFLAGS += -pg
- LDFLAGS += -pg
-endif
-
-.PHONY: all tests tables clean
-
-all: $(OBJ) $(EXE)
-
-
-%-test: $(OBJ) %-test.o
- $(LD) $(LDFLAGS) $(LIBPATH) -o $@ $^ $(LIBS)
-
-%-benchmark: $(OBJ) %-benchmark.o
- $(LD) $(LDFLAGS) $(LIBPATH) -o $@ $^ $(LIBS)
-
-%.o: %.c
- $(CC) $(CFLAGS) $(INCPATH) -c $<
-
-%.o: %.cpp
- $(CXX) $(CXXFLAGS) $(INCPATH) -c $<
-
-tests:
- cd tests; make
-
-tables:
- cd supplement; make
-
-clean:
- rm *.o *-test *-benchmark
diff --git a/bc.c b/bc.c
deleted file mode 100644
index 739fd3f..0000000
--- a/bc.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#include "bc.h"
-
-
-
-#define BC_CODE_GEN
-
-static inline
-unsigned get_num_blocks( unsigned poly_len , unsigned blk_size ) {
- return poly_len/blk_size;
-}
-
-
-static inline
-unsigned deg_si( unsigned si ) {
- return (1< ((1ULL)<
-#include
-#include
-
-#include "bc_to_mono_gen_code.c"
-#include "bc_to_lch_gen_code.c"
-
-
-#define LOG2(X) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((X)) - 1))
-#define MAX(x,y) (((x)>(y))?(x):(y))
-#define MIN(x,y) (((x)<(y))?(x):(y))
-
-static inline
-void xor_down( bc_sto_t * poly , unsigned st , unsigned len , unsigned diff )
-{
-#if 0
- for( unsigned i=0;i>2;
- for( unsigned i=0;i<_len;i++ ) {
- *(poly256-i-1) ^= _mm256_loadu_si256( (__m256i*)(poly+st+diff-(i*4)-4) );
- }
- for( unsigned i=(_len<<2);i=si_degree;i--) {
- for(int j=((int)blk_size)-1;j>=0;j--) {
- poly[(i-deg_diff)*blk_size+j] ^= poly[i*blk_size+j];
- }
- }
-#endif
-}
-
-static inline
-void represent_in_si( bc_sto_t * poly , unsigned n_terms , unsigned blk_size , unsigned si )
-{
- if( 0 == si ) return;
- unsigned num_blocks = get_num_blocks( n_terms , blk_size );
- if( 2 >= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned degree_basic_form_si = deg_si(si);
- if( degree_basic_form_si > degree_in_blocks ) return;
-
-#if 1
- unsigned pow = get_si_2_pow( si , degree_in_blocks );
- while( 0 < pow ) {
- for(unsigned i=0;i>= 1;
- }
-#else
- unsigned pow = get_si_2_pow( si , degree_in_blocks );
- poly_div( poly , n_terms , blk_size , si , pow );
- if( 1 < pow ) {
- represent_in_si( poly , pow*deg_si(si)*blk_size , blk_size , si );
- represent_in_si( poly + pow*deg_si(si)*blk_size , n_terms - pow*deg_si(si)*blk_size , blk_size , si );
- }
-#endif
-}
-
-
-void _bc_to_lch( bc_sto_t * poly , unsigned n_terms , unsigned blk_size )
-{
- unsigned num_blocks = get_num_blocks( n_terms , blk_size );
- if( 2 >= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned si = get_max_si( degree_in_blocks );
- represent_in_si( poly , n_terms , blk_size , si );
-
- unsigned new_blk_size = deg_si(si)*blk_size;
- _bc_to_lch( poly , n_terms , new_blk_size );
- for(unsigned i=0;i>2;
- for( unsigned i=0;i<_len;i++ ) {
- poly256[i] ^= _mm256_loadu_si256( (__m256i*)(poly+st+diff+(i*4)) );
- }
- for( unsigned i=(_len<<2);i= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned degree_basic_form_si = deg_si(si);
- if( degree_basic_form_si > degree_in_blocks ) return;
-
- unsigned pow = 1;
- while( pow*deg_si(si) <= degree_in_blocks ) {
- for(unsigned i=0;i= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned si = get_max_si( degree_in_blocks );
-
-
- unsigned new_blk_size = deg_si(si)*blk_size;
- for(unsigned i=0;i>1;
- for( unsigned i=0;i<_len;i++ ) {
- *(poly256 - i-1) ^= _mm256_loadu_si256( (__m256i*)(poly+st+diff-(i*2)-2) );
- }
- if( len&1 ) {
- poly[st-len] ^= poly[st-len+diff];
- }
-#endif
-}
-
-
-
-static inline
-void poly_div_128( __m128i * poly , unsigned n_terms , unsigned blk_size , unsigned si , unsigned pow )
-{
- if( 0 == si ) return;
- unsigned si_degree = deg_si(si)*pow;
- unsigned deg_diff = si_degree - pow;
- unsigned deg_blk = get_num_blocks( n_terms , blk_size ) -1;
-
- xor_down_128( poly , (deg_blk-deg_diff+1)*blk_size , (deg_blk-si_degree+1)*blk_size , deg_diff*blk_size );
-}
-
-static inline
-void represent_in_si_128( __m128i * poly , unsigned n_terms , unsigned blk_size , unsigned si )
-{
- if( 0 == si ) return;
- unsigned num_blocks = get_num_blocks( n_terms , blk_size );
- if( 2 >= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned degree_basic_form_si = deg_si(si);
- if( degree_basic_form_si > degree_in_blocks ) return;
-
-#if 1
- unsigned pow = get_si_2_pow( si , degree_in_blocks );
- while( 0 < pow ) {
- for(unsigned i=0;i>= 1;
- }
-#else
- unsigned pow = get_si_2_pow( si , degree_in_blocks );
- poly_div( poly , n_terms , blk_size , si , pow );
- if( 1 < pow ) {
- represent_in_si( poly , pow*deg_si(si)*blk_size , blk_size , si );
- represent_in_si( poly + pow*deg_si(si)*blk_size , n_terms - pow*deg_si(si)*blk_size , blk_size , si );
- }
-#endif
-}
-
-
-void _bc_to_lch_128( __m128i * poly , unsigned n_terms , unsigned blk_size )
-{
- unsigned num_blocks = get_num_blocks( n_terms , blk_size );
- if( 2 >= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned si = get_max_si( degree_in_blocks );
- represent_in_si_128( poly , n_terms , blk_size , si );
-
- unsigned new_blk_size = deg_si(si)*blk_size;
- _bc_to_lch_128( poly , n_terms , new_blk_size );
- for(unsigned i=0;i>1;
- for( unsigned i=0;i<_len;i++ ) {
- poly256[i] ^= _mm256_loadu_si256( (__m256i*)(poly+st+diff+(i*2)) );
- }
- if( len&1 ) {
- poly[st+len-1] ^= poly[st+len-1+diff];
- }
-#endif
-}
-
-
-static inline
-void i_poly_div_128( __m128i * poly , unsigned n_terms , unsigned blk_size , unsigned si , unsigned pow )
-{
- if( 0 == si ) return;
- unsigned si_degree = deg_si(si)*pow;
- unsigned deg_diff = si_degree - pow;
- unsigned deg_blk = get_num_blocks( n_terms , blk_size ) -1;
-
-#if 1
- xor_up_128( poly , blk_size*(si_degree-deg_diff) , (deg_blk-si_degree+1)*blk_size , deg_diff*blk_size );
-#else
- for(unsigned i=si_degree;i<=deg_blk;i++) {
- for(unsigned j=0; j= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned degree_basic_form_si = deg_si(si);
- if( degree_basic_form_si > degree_in_blocks ) return;
-
- unsigned pow = 1;
- while( pow*deg_si(si) <= degree_in_blocks ) {
- for(unsigned i=0;i= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
-
-//printf("deg: %d\n", degree_in_blocks);
- unsigned si = get_max_si( degree_in_blocks );
-//printf("si: %d\n",si);
-
- unsigned new_blk_size = deg_si(si)*blk_size;
-//printf("new blksize: %d\n", new_blk_size);
- for(unsigned i=0;i0;){
- i--;
- poly[dest_idx+i] ^= poly[src_idx+i];
- }
-}
-
-static inline
-void __xor_up_256( __m256i * poly , unsigned dest_idx , unsigned src_idx , unsigned len )
-{
- for(unsigned i=0;i=0;i--) poly[l_st+i] ^= poly[len+i];
-}
-
-static inline
-void xor_up_256( __m256i * poly , unsigned st , unsigned len , unsigned diff )
-{
- __xor_up_256( poly , st , diff + st , len );
-// for( unsigned i=0;i= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned degree_basic_form_si = deg_si(si);
- if( degree_basic_form_si > degree_in_blocks ) return;
-
-#if 1
- unsigned pow = get_si_2_pow( si , degree_in_blocks );
- while( 0 < pow ) {
- for(unsigned i=0;i>= 1;
- }
-#else
- unsigned pow = get_si_2_pow( si , degree_in_blocks );
- poly_div( poly , n_terms , blk_size , si , pow );
- if( 1 < pow ) {
- represent_in_si( poly , pow*deg_si(si)*blk_size , blk_size , si );
- represent_in_si( poly + pow*deg_si(si)*blk_size , n_terms - pow*deg_si(si)*blk_size , blk_size , si );
- }
-#endif
-}
-
-
-void _bc_to_lch_256( __m256i * poly , unsigned n_terms , unsigned blk_size )
-{
-
- unsigned num_blocks = get_num_blocks( n_terms , blk_size );
- if( 2 >= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned si = get_max_si( degree_in_blocks );
- represent_in_si_256( poly , n_terms , blk_size , si );
-
- unsigned new_blk_size = deg_si(si)*blk_size;
- _bc_to_lch_256( poly , n_terms , new_blk_size );
- for(unsigned i=0;i= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned degree_basic_form_si = deg_si(si);
- if( degree_basic_form_si > degree_in_blocks ) return;
-
- unsigned pow = 1;
- while( pow*deg_si(si) <= degree_in_blocks ) {
- for(unsigned i=0;i= num_blocks ) return;
- unsigned degree_in_blocks = num_blocks - 1;
- unsigned si = get_max_si( degree_in_blocks );
-
- unsigned new_blk_size = deg_si(si)*blk_size;
- for(unsigned i=0;i>1;
- poly256[unit_2] ^= _sh_op_zerohigh[_op](zero,poly256[unit-1]);
- for(unsigned i=0;i= n_256 ) return;
- unsigned log_n = __builtin_ctz( n_256 );
- __m256i zero = _mm256_setzero_si256();
-
- while( log_n > 8 ) {
- unsigned unit = 1<>1;
- for(unsigned j=0;j0 ; i--) {
- unsigned unit = (1<>1;
- poly256[0] ^= _sh_op[_op](poly256[unit_2],zero);
- for(unsigned i=0;i= n_256 ) return;
- unsigned log_n = __builtin_ctz( n_256 );
- __m256i zero = _mm256_setzero_si256();
-
- unsigned _log_n = (log_n>8)? 8 : log_n;
- for(unsigned i=1; i<=_log_n ; i++) {
- unsigned unit = (1<>1;
- for(unsigned j=0;j>2;
-
- varsub_x256( poly256 , n_256 );
-#ifdef BC_CODE_GEN
- int logn = LOG2(n_256);
- bc_to_lch_256_30_12(poly256,logn);
- for(int i=0;i<(1<<(MAX(0,logn-19)));++i){
- bc_to_lch_256_19_17(poly256+i*(1<<19),MIN(19,logn));
- }
- for(int i=0;i<(1<<(MAX(0,logn-16)));++i){
- bc_to_lch_256_16(poly256+i*(1<<16), MIN(16,logn));
- }
-#else
- _bc_to_lch_256( poly256 , n_256 , 1 );
-#endif
-}
-
-
-void bc_to_mono_2_unit256( bc_sto_t * poly , unsigned n_terms )
-{
- assert( 0 == ( n_terms&(n_terms-1) ) );
- assert( 4 <= n_terms );
-
- __m256i * poly256 = (__m256i*) poly;
- unsigned n_256 = n_terms>>2;
-
-#ifdef BC_CODE_GEN
- int logn = LOG2(n_256);
- for(int i=0;i<(1<<(MAX(0,logn-16)));++i){
- bc_to_mono_256_16(poly256+i*(1<<16), MIN(16,logn));
- }
- for(int i=0;i<(1<<(MAX(0,logn-19)));++i){
- bc_to_mono_256_19_17(poly256+i*(1<<19),MIN(19,logn));
- }
- bc_to_mono_256_30_20(poly256,logn);
-#else
- _bc_to_mono_256( poly256 , n_256 , 1 );
-#endif
- i_varsub_x256( poly256 , n_256 );
-}
-
-
diff --git a/bc.h b/bc.h
deleted file mode 100644
index 0b0bd07..0000000
--- a/bc.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#ifndef _BC_H_
-#define _BC_H_
-
-#include
-
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef uint64_t bc_sto_t;
-
-
-void bc_to_lch( bc_sto_t * poly , unsigned n_terms );
-
-void bc_to_mono( bc_sto_t * poly , unsigned n_terms );
-
-
-void bc_to_lch_128( bc_sto_t * poly , unsigned n_terms );
-
-void bc_to_mono_128( bc_sto_t * poly , unsigned n_terms );
-
-
-void bc_to_lch_256( bc_sto_t * poly , unsigned n_terms );
-
-void bc_to_mono_256( bc_sto_t * poly , unsigned n_terms );
-
-
-
-void bc_to_lch_2( bc_sto_t * poly , unsigned n_terms );
-
-void bc_to_mono_2( bc_sto_t * poly , unsigned n_terms );
-
-
-void bc_to_lch_2_unit256( bc_sto_t * poly , unsigned n_terms );
-
-void bc_to_mono_2_unit256( bc_sto_t * poly , unsigned n_terms );
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif
diff --git a/bc_to_lch_gen_code.c b/bc_to_lch_gen_code.c
deleted file mode 100644
index 585e2e1..0000000
--- a/bc_to_lch_gen_code.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
-Copyright (C) 2018 Wen-Ding Li
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-void bc_to_lch_256_30_12(__m256i* poly, int logn){
-for(int offset=(1<<30);offset<(1<=offset+(1<<30)-1006632960;--i)poly[i]^=poly[i+805306368];
-for(int i=offset+(1<<30)-1-1006632960;i>=offset+(1<<30)-1056964608;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960];
-for(int i=offset+(1<<30)-1-1056964608;i>=offset+(1<<30)-1069547520;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608];
-for(int i=offset+(1<<30)-1-1069547520;i>=offset+(1<<30)-1072693248;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520];
-for(int i=offset+(1<<30)-1-1072693248;i>=offset+(1<<30)-1073479680;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248];
-for(int i=offset+(1<<30)-1-1073479680;i>=offset+(1<<30)-1073676288;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680];
-for(int i=offset+(1<<30)-1-1073676288;i>=offset+(1<<30)-1073725440;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288];
-for(int i=offset+(1<<30)-1-1073725440;i>=offset+(1<<30)-1073737728;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440];
-for(int i=offset+(1<<30)-1-1073737728;i>=offset+(1<<30)-1073740800;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728];
-for(int i=offset+(1<<30)-1-1073740800;i>=offset+(1<<30)-1073741568;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800];
-for(int i=offset+(1<<30)-1-1073741568;i>=offset+(1<<30)-1073741760;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568];
-for(int i=offset+(1<<30)-1-1073741760;i>=offset+(1<<30)-1073741808;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760];
-for(int i=offset+(1<<30)-1-1073741808;i>=offset+(1<<30)-1073741820;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808];
-for(int i=offset+(1<<30)-1-1073741820;i>=offset+(1<<30)-1073741823;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820];
-for(int i=offset+(1<<30)-1-1073741823;i>=offset+(1<<30)-1073741824;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-0;i>=offset-805306368;--i)poly[i]^=poly[i+805306368]^poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-805306368;i>=offset-1006632960;--i)poly[i]^=poly[i+1006632960]^poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1006632960;i>=offset-1056964608;--i)poly[i]^=poly[i+1056964608]^poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1056964608;i>=offset-1069547520;--i)poly[i]^=poly[i+1069547520]^poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1069547520;i>=offset-1072693248;--i)poly[i]^=poly[i+1072693248]^poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1072693248;i>=offset-1073479680;--i)poly[i]^=poly[i+1073479680]^poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073479680;i>=offset-1073676288;--i)poly[i]^=poly[i+1073676288]^poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073676288;i>=offset-1073725440;--i)poly[i]^=poly[i+1073725440]^poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073725440;i>=offset-1073737728;--i)poly[i]^=poly[i+1073737728]^poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073737728;i>=offset-1073740800;--i)poly[i]^=poly[i+1073740800]^poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073740800;i>=offset-1073741568;--i)poly[i]^=poly[i+1073741568]^poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073741568;i>=offset-1073741760;--i)poly[i]^=poly[i+1073741760]^poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073741760;i>=offset-1073741808;--i)poly[i]^=poly[i+1073741808]^poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073741808;i>=offset-1073741820;--i)poly[i]^=poly[i+1073741820]^poly[i+1073741823];
-for(int i=offset-1-1073741820;i>=offset-1073741823;--i)poly[i]^=poly[i+1073741823];
-
-}
-for(int offset=(1<<29);offset<(1<=offset+(1<<29)-503316480;--i)poly[i]^=poly[i+268435456];
-for(int i=offset+(1<<29)-1-503316480;i>=offset+(1<<29)-520093696;--i)poly[i]^=poly[i+268435456]^poly[i+503316480];
-for(int i=offset+(1<<29)-1-520093696;i>=offset+(1<<29)-534773760;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696];
-for(int i=offset+(1<<29)-1-534773760;i>=offset+(1<<29)-535822336;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760];
-for(int i=offset+(1<<29)-1-535822336;i>=offset+(1<<29)-536739840;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336];
-for(int i=offset+(1<<29)-1-536739840;i>=offset+(1<<29)-536805376;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840];
-for(int i=offset+(1<<29)-1-536805376;i>=offset+(1<<29)-536862720;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376];
-for(int i=offset+(1<<29)-1-536862720;i>=offset+(1<<29)-536866816;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720];
-for(int i=offset+(1<<29)-1-536866816;i>=offset+(1<<29)-536870400;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816];
-for(int i=offset+(1<<29)-1-536870400;i>=offset+(1<<29)-536870656;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400];
-for(int i=offset+(1<<29)-1-536870656;i>=offset+(1<<29)-536870880;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656];
-for(int i=offset+(1<<29)-1-536870880;i>=offset+(1<<29)-536870896;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880];
-for(int i=offset+(1<<29)-1-536870896;i>=offset+(1<<29)-536870910;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896];
-for(int i=offset+(1<<29)-1-536870910;i>=offset+(1<<29)-536870911;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910];
-for(int i=offset+(1<<29)-1-536870911;i>=offset+(1<<29)-536870912;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-0;i>=offset-268435456;--i)poly[i]^=poly[i+268435456]^poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-268435456;i>=offset-503316480;--i)poly[i]^=poly[i+503316480]^poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-503316480;i>=offset-520093696;--i)poly[i]^=poly[i+520093696]^poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-520093696;i>=offset-534773760;--i)poly[i]^=poly[i+534773760]^poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-534773760;i>=offset-535822336;--i)poly[i]^=poly[i+535822336]^poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-535822336;i>=offset-536739840;--i)poly[i]^=poly[i+536739840]^poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536739840;i>=offset-536805376;--i)poly[i]^=poly[i+536805376]^poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536805376;i>=offset-536862720;--i)poly[i]^=poly[i+536862720]^poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536862720;i>=offset-536866816;--i)poly[i]^=poly[i+536866816]^poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536866816;i>=offset-536870400;--i)poly[i]^=poly[i+536870400]^poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536870400;i>=offset-536870656;--i)poly[i]^=poly[i+536870656]^poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536870656;i>=offset-536870880;--i)poly[i]^=poly[i+536870880]^poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536870880;i>=offset-536870896;--i)poly[i]^=poly[i+536870896]^poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536870896;i>=offset-536870910;--i)poly[i]^=poly[i+536870910]^poly[i+536870911];
-for(int i=offset-1-536870910;i>=offset-536870911;--i)poly[i]^=poly[i+536870911];
-
-}
-for(int offset=(1<<28);offset<(1<=offset+(1<<28)-267386880;--i)poly[i]^=poly[i+251658240];
-for(int i=offset+(1<<28)-1-267386880;i>=offset+(1<<28)-268369920;--i)poly[i]^=poly[i+251658240]^poly[i+267386880];
-for(int i=offset+(1<<28)-1-268369920;i>=offset+(1<<28)-268431360;--i)poly[i]^=poly[i+251658240]^poly[i+267386880]^poly[i+268369920];
-for(int i=offset+(1<<28)-1-268431360;i>=offset+(1<<28)-268435200;--i)poly[i]^=poly[i+251658240]^poly[i+267386880]^poly[i+268369920]^poly[i+268431360];
-for(int i=offset+(1<<28)-1-268435200;i>=offset+(1<<28)-268435440;--i)poly[i]^=poly[i+251658240]^poly[i+267386880]^poly[i+268369920]^poly[i+268431360]^poly[i+268435200];
-for(int i=offset+(1<<28)-1-268435440;i>=offset+(1<<28)-268435455;--i)poly[i]^=poly[i+251658240]^poly[i+267386880]^poly[i+268369920]^poly[i+268431360]^poly[i+268435200]^poly[i+268435440];
-for(int i=offset+(1<<28)-1-268435455;i>=offset+(1<<28)-268435456;--i)poly[i]^=poly[i+251658240]^poly[i+267386880]^poly[i+268369920]^poly[i+268431360]^poly[i+268435200]^poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-0;i>=offset-251658240;--i)poly[i]^=poly[i+251658240]^poly[i+267386880]^poly[i+268369920]^poly[i+268431360]^poly[i+268435200]^poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-251658240;i>=offset-267386880;--i)poly[i]^=poly[i+267386880]^poly[i+268369920]^poly[i+268431360]^poly[i+268435200]^poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-267386880;i>=offset-268369920;--i)poly[i]^=poly[i+268369920]^poly[i+268431360]^poly[i+268435200]^poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-268369920;i>=offset-268431360;--i)poly[i]^=poly[i+268431360]^poly[i+268435200]^poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-268431360;i>=offset-268435200;--i)poly[i]^=poly[i+268435200]^poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-268435200;i>=offset-268435440;--i)poly[i]^=poly[i+268435440]^poly[i+268435455];
-for(int i=offset-1-268435440;i>=offset-268435455;--i)poly[i]^=poly[i+268435455];
-
-}
-for(int offset=(1<<27);offset<(1<=offset+(1<<27)-100663296;--i)poly[i]^=poly[i+67108864];
-for(int i=offset+(1<<27)-1-100663296;i>=offset+(1<<27)-117440512;--i)poly[i]^=poly[i+67108864]^poly[i+100663296];
-for(int i=offset+(1<<27)-1-117440512;i>=offset+(1<<27)-133693440;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512];
-for(int i=offset+(1<<27)-1-133693440;i>=offset+(1<<27)-133955584;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440];
-for(int i=offset+(1<<27)-1-133955584;i>=offset+(1<<27)-134086656;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584];
-for(int i=offset+(1<<27)-1-134086656;i>=offset+(1<<27)-134152192;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656];
-for(int i=offset+(1<<27)-1-134152192;i>=offset+(1<<27)-134215680;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192];
-for(int i=offset+(1<<27)-1-134215680;i>=offset+(1<<27)-134216704;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680];
-for(int i=offset+(1<<27)-1-134216704;i>=offset+(1<<27)-134217216;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704];
-for(int i=offset+(1<<27)-1-134217216;i>=offset+(1<<27)-134217472;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216];
-for(int i=offset+(1<<27)-1-134217472;i>=offset+(1<<27)-134217720;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472];
-for(int i=offset+(1<<27)-1-134217720;i>=offset+(1<<27)-134217724;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720];
-for(int i=offset+(1<<27)-1-134217724;i>=offset+(1<<27)-134217726;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724];
-for(int i=offset+(1<<27)-1-134217726;i>=offset+(1<<27)-134217727;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726];
-for(int i=offset+(1<<27)-1-134217727;i>=offset+(1<<27)-134217728;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-0;i>=offset-67108864;--i)poly[i]^=poly[i+67108864]^poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-67108864;i>=offset-100663296;--i)poly[i]^=poly[i+100663296]^poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-100663296;i>=offset-117440512;--i)poly[i]^=poly[i+117440512]^poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-117440512;i>=offset-133693440;--i)poly[i]^=poly[i+133693440]^poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-133693440;i>=offset-133955584;--i)poly[i]^=poly[i+133955584]^poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-133955584;i>=offset-134086656;--i)poly[i]^=poly[i+134086656]^poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134086656;i>=offset-134152192;--i)poly[i]^=poly[i+134152192]^poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134152192;i>=offset-134215680;--i)poly[i]^=poly[i+134215680]^poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134215680;i>=offset-134216704;--i)poly[i]^=poly[i+134216704]^poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134216704;i>=offset-134217216;--i)poly[i]^=poly[i+134217216]^poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134217216;i>=offset-134217472;--i)poly[i]^=poly[i+134217472]^poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134217472;i>=offset-134217720;--i)poly[i]^=poly[i+134217720]^poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134217720;i>=offset-134217724;--i)poly[i]^=poly[i+134217724]^poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134217724;i>=offset-134217726;--i)poly[i]^=poly[i+134217726]^poly[i+134217727];
-for(int i=offset-1-134217726;i>=offset-134217727;--i)poly[i]^=poly[i+134217727];
-
-}
-for(int offset=(1<<26);offset<(1<=offset+(1<<26)-66846720;--i)poly[i]^=poly[i+50331648];
-for(int i=offset+(1<<26)-1-66846720;i>=offset+(1<<26)-67043328;--i)poly[i]^=poly[i+50331648]^poly[i+66846720];
-for(int i=offset+(1<<26)-1-67043328;i>=offset+(1<<26)-67107840;--i)poly[i]^=poly[i+50331648]^poly[i+66846720]^poly[i+67043328];
-for(int i=offset+(1<<26)-1-67107840;i>=offset+(1<<26)-67108608;--i)poly[i]^=poly[i+50331648]^poly[i+66846720]^poly[i+67043328]^poly[i+67107840];
-for(int i=offset+(1<<26)-1-67108608;i>=offset+(1<<26)-67108860;--i)poly[i]^=poly[i+50331648]^poly[i+66846720]^poly[i+67043328]^poly[i+67107840]^poly[i+67108608];
-for(int i=offset+(1<<26)-1-67108860;i>=offset+(1<<26)-67108863;--i)poly[i]^=poly[i+50331648]^poly[i+66846720]^poly[i+67043328]^poly[i+67107840]^poly[i+67108608]^poly[i+67108860];
-for(int i=offset+(1<<26)-1-67108863;i>=offset+(1<<26)-67108864;--i)poly[i]^=poly[i+50331648]^poly[i+66846720]^poly[i+67043328]^poly[i+67107840]^poly[i+67108608]^poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-0;i>=offset-50331648;--i)poly[i]^=poly[i+50331648]^poly[i+66846720]^poly[i+67043328]^poly[i+67107840]^poly[i+67108608]^poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-50331648;i>=offset-66846720;--i)poly[i]^=poly[i+66846720]^poly[i+67043328]^poly[i+67107840]^poly[i+67108608]^poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-66846720;i>=offset-67043328;--i)poly[i]^=poly[i+67043328]^poly[i+67107840]^poly[i+67108608]^poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-67043328;i>=offset-67107840;--i)poly[i]^=poly[i+67107840]^poly[i+67108608]^poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-67107840;i>=offset-67108608;--i)poly[i]^=poly[i+67108608]^poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-67108608;i>=offset-67108860;--i)poly[i]^=poly[i+67108860]^poly[i+67108863];
-for(int i=offset-1-67108860;i>=offset-67108863;--i)poly[i]^=poly[i+67108863];
-
-}
-for(int offset=(1<<25);offset<(1<=offset+(1<<25)-33423360;--i)poly[i]^=poly[i+16777216];
-for(int i=offset+(1<<25)-1-33423360;i>=offset+(1<<25)-33488896;--i)poly[i]^=poly[i+16777216]^poly[i+33423360];
-for(int i=offset+(1<<25)-1-33488896;i>=offset+(1<<25)-33553920;--i)poly[i]^=poly[i+16777216]^poly[i+33423360]^poly[i+33488896];
-for(int i=offset+(1<<25)-1-33553920;i>=offset+(1<<25)-33554176;--i)poly[i]^=poly[i+16777216]^poly[i+33423360]^poly[i+33488896]^poly[i+33553920];
-for(int i=offset+(1<<25)-1-33554176;i>=offset+(1<<25)-33554430;--i)poly[i]^=poly[i+16777216]^poly[i+33423360]^poly[i+33488896]^poly[i+33553920]^poly[i+33554176];
-for(int i=offset+(1<<25)-1-33554430;i>=offset+(1<<25)-33554431;--i)poly[i]^=poly[i+16777216]^poly[i+33423360]^poly[i+33488896]^poly[i+33553920]^poly[i+33554176]^poly[i+33554430];
-for(int i=offset+(1<<25)-1-33554431;i>=offset+(1<<25)-33554432;--i)poly[i]^=poly[i+16777216]^poly[i+33423360]^poly[i+33488896]^poly[i+33553920]^poly[i+33554176]^poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-0;i>=offset-16777216;--i)poly[i]^=poly[i+16777216]^poly[i+33423360]^poly[i+33488896]^poly[i+33553920]^poly[i+33554176]^poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-16777216;i>=offset-33423360;--i)poly[i]^=poly[i+33423360]^poly[i+33488896]^poly[i+33553920]^poly[i+33554176]^poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-33423360;i>=offset-33488896;--i)poly[i]^=poly[i+33488896]^poly[i+33553920]^poly[i+33554176]^poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-33488896;i>=offset-33553920;--i)poly[i]^=poly[i+33553920]^poly[i+33554176]^poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-33553920;i>=offset-33554176;--i)poly[i]^=poly[i+33554176]^poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-33554176;i>=offset-33554430;--i)poly[i]^=poly[i+33554430]^poly[i+33554431];
-for(int i=offset-1-33554430;i>=offset-33554431;--i)poly[i]^=poly[i+33554431];
-
-}
-for(int offset=(1<<24);offset<(1<=offset+(1<<24)-16776960;--i)poly[i]^=poly[i+16711680];
-for(int i=offset+(1<<24)-1-16776960;i>=offset+(1<<24)-16777215;--i)poly[i]^=poly[i+16711680]^poly[i+16776960];
-for(int i=offset+(1<<24)-1-16777215;i>=offset+(1<<24)-16777216;--i)poly[i]^=poly[i+16711680]^poly[i+16776960]^poly[i+16777215];
-for(int i=offset-1-0;i>=offset-16711680;--i)poly[i]^=poly[i+16711680]^poly[i+16776960]^poly[i+16777215];
-for(int i=offset-1-16711680;i>=offset-16776960;--i)poly[i]^=poly[i+16776960]^poly[i+16777215];
-for(int i=offset-1-16776960;i>=offset-16777215;--i)poly[i]^=poly[i+16777215];
-
-}
-for(int offset=(1<<23);offset<(1<=offset+(1<<23)-6291456;--i)poly[i]^=poly[i+4194304];
-for(int i=offset+(1<<23)-1-6291456;i>=offset+(1<<23)-7340032;--i)poly[i]^=poly[i+4194304]^poly[i+6291456];
-for(int i=offset+(1<<23)-1-7340032;i>=offset+(1<<23)-7864320;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032];
-for(int i=offset+(1<<23)-1-7864320;i>=offset+(1<<23)-8126464;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320];
-for(int i=offset+(1<<23)-1-8126464;i>=offset+(1<<23)-8257536;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464];
-for(int i=offset+(1<<23)-1-8257536;i>=offset+(1<<23)-8323072;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536];
-for(int i=offset+(1<<23)-1-8323072;i>=offset+(1<<23)-8388480;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072];
-for(int i=offset+(1<<23)-1-8388480;i>=offset+(1<<23)-8388544;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480];
-for(int i=offset+(1<<23)-1-8388544;i>=offset+(1<<23)-8388576;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544];
-for(int i=offset+(1<<23)-1-8388576;i>=offset+(1<<23)-8388592;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576];
-for(int i=offset+(1<<23)-1-8388592;i>=offset+(1<<23)-8388600;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592];
-for(int i=offset+(1<<23)-1-8388600;i>=offset+(1<<23)-8388604;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600];
-for(int i=offset+(1<<23)-1-8388604;i>=offset+(1<<23)-8388606;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604];
-for(int i=offset+(1<<23)-1-8388606;i>=offset+(1<<23)-8388607;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606];
-for(int i=offset+(1<<23)-1-8388607;i>=offset+(1<<23)-8388608;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-0;i>=offset-4194304;--i)poly[i]^=poly[i+4194304]^poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-4194304;i>=offset-6291456;--i)poly[i]^=poly[i+6291456]^poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-6291456;i>=offset-7340032;--i)poly[i]^=poly[i+7340032]^poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-7340032;i>=offset-7864320;--i)poly[i]^=poly[i+7864320]^poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-7864320;i>=offset-8126464;--i)poly[i]^=poly[i+8126464]^poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8126464;i>=offset-8257536;--i)poly[i]^=poly[i+8257536]^poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8257536;i>=offset-8323072;--i)poly[i]^=poly[i+8323072]^poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8323072;i>=offset-8388480;--i)poly[i]^=poly[i+8388480]^poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388480;i>=offset-8388544;--i)poly[i]^=poly[i+8388544]^poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388544;i>=offset-8388576;--i)poly[i]^=poly[i+8388576]^poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388576;i>=offset-8388592;--i)poly[i]^=poly[i+8388592]^poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388592;i>=offset-8388600;--i)poly[i]^=poly[i+8388600]^poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388600;i>=offset-8388604;--i)poly[i]^=poly[i+8388604]^poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388604;i>=offset-8388606;--i)poly[i]^=poly[i+8388606]^poly[i+8388607];
-for(int i=offset-1-8388606;i>=offset-8388607;--i)poly[i]^=poly[i+8388607];
-
-}
-for(int offset=(1<<22);offset<(1<=offset+(1<<22)-3932160;--i)poly[i]^=poly[i+3145728];
-for(int i=offset+(1<<22)-1-3932160;i>=offset+(1<<22)-4128768;--i)poly[i]^=poly[i+3145728]^poly[i+3932160];
-for(int i=offset+(1<<22)-1-4128768;i>=offset+(1<<22)-4194240;--i)poly[i]^=poly[i+3145728]^poly[i+3932160]^poly[i+4128768];
-for(int i=offset+(1<<22)-1-4194240;i>=offset+(1<<22)-4194288;--i)poly[i]^=poly[i+3145728]^poly[i+3932160]^poly[i+4128768]^poly[i+4194240];
-for(int i=offset+(1<<22)-1-4194288;i>=offset+(1<<22)-4194300;--i)poly[i]^=poly[i+3145728]^poly[i+3932160]^poly[i+4128768]^poly[i+4194240]^poly[i+4194288];
-for(int i=offset+(1<<22)-1-4194300;i>=offset+(1<<22)-4194303;--i)poly[i]^=poly[i+3145728]^poly[i+3932160]^poly[i+4128768]^poly[i+4194240]^poly[i+4194288]^poly[i+4194300];
-for(int i=offset+(1<<22)-1-4194303;i>=offset+(1<<22)-4194304;--i)poly[i]^=poly[i+3145728]^poly[i+3932160]^poly[i+4128768]^poly[i+4194240]^poly[i+4194288]^poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-0;i>=offset-3145728;--i)poly[i]^=poly[i+3145728]^poly[i+3932160]^poly[i+4128768]^poly[i+4194240]^poly[i+4194288]^poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-3145728;i>=offset-3932160;--i)poly[i]^=poly[i+3932160]^poly[i+4128768]^poly[i+4194240]^poly[i+4194288]^poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-3932160;i>=offset-4128768;--i)poly[i]^=poly[i+4128768]^poly[i+4194240]^poly[i+4194288]^poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-4128768;i>=offset-4194240;--i)poly[i]^=poly[i+4194240]^poly[i+4194288]^poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-4194240;i>=offset-4194288;--i)poly[i]^=poly[i+4194288]^poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-4194288;i>=offset-4194300;--i)poly[i]^=poly[i+4194300]^poly[i+4194303];
-for(int i=offset-1-4194300;i>=offset-4194303;--i)poly[i]^=poly[i+4194303];
-
-}
-for(int offset=(1<<21);offset<(1<=offset+(1<<21)-1966080;--i)poly[i]^=poly[i+1048576];
-for(int i=offset+(1<<21)-1-1966080;i>=offset+(1<<21)-2031616;--i)poly[i]^=poly[i+1048576]^poly[i+1966080];
-for(int i=offset+(1<<21)-1-2031616;i>=offset+(1<<21)-2097120;--i)poly[i]^=poly[i+1048576]^poly[i+1966080]^poly[i+2031616];
-for(int i=offset+(1<<21)-1-2097120;i>=offset+(1<<21)-2097136;--i)poly[i]^=poly[i+1048576]^poly[i+1966080]^poly[i+2031616]^poly[i+2097120];
-for(int i=offset+(1<<21)-1-2097136;i>=offset+(1<<21)-2097150;--i)poly[i]^=poly[i+1048576]^poly[i+1966080]^poly[i+2031616]^poly[i+2097120]^poly[i+2097136];
-for(int i=offset+(1<<21)-1-2097150;i>=offset+(1<<21)-2097151;--i)poly[i]^=poly[i+1048576]^poly[i+1966080]^poly[i+2031616]^poly[i+2097120]^poly[i+2097136]^poly[i+2097150];
-for(int i=offset+(1<<21)-1-2097151;i>=offset+(1<<21)-2097152;--i)poly[i]^=poly[i+1048576]^poly[i+1966080]^poly[i+2031616]^poly[i+2097120]^poly[i+2097136]^poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-0;i>=offset-1048576;--i)poly[i]^=poly[i+1048576]^poly[i+1966080]^poly[i+2031616]^poly[i+2097120]^poly[i+2097136]^poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-1048576;i>=offset-1966080;--i)poly[i]^=poly[i+1966080]^poly[i+2031616]^poly[i+2097120]^poly[i+2097136]^poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-1966080;i>=offset-2031616;--i)poly[i]^=poly[i+2031616]^poly[i+2097120]^poly[i+2097136]^poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-2031616;i>=offset-2097120;--i)poly[i]^=poly[i+2097120]^poly[i+2097136]^poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-2097120;i>=offset-2097136;--i)poly[i]^=poly[i+2097136]^poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-2097136;i>=offset-2097150;--i)poly[i]^=poly[i+2097150]^poly[i+2097151];
-for(int i=offset-1-2097150;i>=offset-2097151;--i)poly[i]^=poly[i+2097151];
-
-}
-for(int offset=(1<<20);offset<(1<=offset+(1<<20)-1048560;--i)poly[i]^=poly[i+983040];
-for(int i=offset+(1<<20)-1-1048560;i>=offset+(1<<20)-1048575;--i)poly[i]^=poly[i+983040]^poly[i+1048560];
-for(int i=offset+(1<<20)-1-1048575;i>=offset+(1<<20)-1048576;--i)poly[i]^=poly[i+983040]^poly[i+1048560]^poly[i+1048575];
-for(int i=offset-1-0;i>=offset-983040;--i)poly[i]^=poly[i+983040]^poly[i+1048560]^poly[i+1048575];
-for(int i=offset-1-983040;i>=offset-1048560;--i)poly[i]^=poly[i+1048560]^poly[i+1048575];
-for(int i=offset-1-1048560;i>=offset-1048575;--i)poly[i]^=poly[i+1048575];
-
-}
-for(int offset=(1<<19);offset<(1<=offset+(1<<19)-393216;--i)poly[i]^=poly[i+262144];
-for(int i=offset+(1<<19)-1-393216;i>=offset+(1<<19)-458752;--i)poly[i]^=poly[i+262144]^poly[i+393216];
-for(int i=offset+(1<<19)-1-458752;i>=offset+(1<<19)-524280;--i)poly[i]^=poly[i+262144]^poly[i+393216]^poly[i+458752];
-for(int i=offset+(1<<19)-1-524280;i>=offset+(1<<19)-524284;--i)poly[i]^=poly[i+262144]^poly[i+393216]^poly[i+458752]^poly[i+524280];
-for(int i=offset+(1<<19)-1-524284;i>=offset+(1<<19)-524286;--i)poly[i]^=poly[i+262144]^poly[i+393216]^poly[i+458752]^poly[i+524280]^poly[i+524284];
-for(int i=offset+(1<<19)-1-524286;i>=offset+(1<<19)-524287;--i)poly[i]^=poly[i+262144]^poly[i+393216]^poly[i+458752]^poly[i+524280]^poly[i+524284]^poly[i+524286];
-for(int i=offset+(1<<19)-1-524287;i>=offset+(1<<19)-524288;--i)poly[i]^=poly[i+262144]^poly[i+393216]^poly[i+458752]^poly[i+524280]^poly[i+524284]^poly[i+524286]^poly[i+524287];
-for(int i=offset-1-0;i>=offset-262144;--i)poly[i]^=poly[i+262144]^poly[i+393216]^poly[i+458752]^poly[i+524280]^poly[i+524284]^poly[i+524286]^poly[i+524287];
-for(int i=offset-1-262144;i>=offset-393216;--i)poly[i]^=poly[i+393216]^poly[i+458752]^poly[i+524280]^poly[i+524284]^poly[i+524286]^poly[i+524287];
-for(int i=offset-1-393216;i>=offset-458752;--i)poly[i]^=poly[i+458752]^poly[i+524280]^poly[i+524284]^poly[i+524286]^poly[i+524287];
-for(int i=offset-1-458752;i>=offset-524280;--i)poly[i]^=poly[i+524280]^poly[i+524284]^poly[i+524286]^poly[i+524287];
-for(int i=offset-1-524280;i>=offset-524284;--i)poly[i]^=poly[i+524284]^poly[i+524286]^poly[i+524287];
-for(int i=offset-1-524284;i>=offset-524286;--i)poly[i]^=poly[i+524286]^poly[i+524287];
-for(int i=offset-1-524286;i>=offset-524287;--i)poly[i]^=poly[i+524287];
-
-}
-}
-static
-void bc_to_lch_256_19_17(__m256i* poly, int logn){
-for(int offset=(1<<18);offset<(1<=offset+(1<<18)-262140;--i)poly[i]^=poly[i+196608];
-for(int i=offset+(1<<18)-1-262140;i>=offset+(1<<18)-262143;--i)poly[i]^=poly[i+196608]^poly[i+262140];
-for(int i=offset+(1<<18)-1-262143;i>=offset+(1<<18)-262144;--i)poly[i]^=poly[i+196608]^poly[i+262140]^poly[i+262143];
-for(int i=offset-1-0;i>=offset-196608;--i)poly[i]^=poly[i+196608]^poly[i+262140]^poly[i+262143];
-for(int i=offset-1-196608;i>=offset-262140;--i)poly[i]^=poly[i+262140]^poly[i+262143];
-for(int i=offset-1-262140;i>=offset-262143;--i)poly[i]^=poly[i+262143];
-
-}
-for(int offset=(1<<17);offset<(1<=offset+(1<<17)-131070;--i)poly[i]^=poly[i+65536];
-for(int i=offset+(1<<17)-1-131070;i>=offset+(1<<17)-131071;--i)poly[i]^=poly[i+65536]^poly[i+131070];
-for(int i=offset+(1<<17)-1-131071;i>=offset+(1<<17)-131072;--i)poly[i]^=poly[i+65536]^poly[i+131070]^poly[i+131071];
-for(int i=offset-1-0;i>=offset-65536;--i)poly[i]^=poly[i+65536]^poly[i+131070]^poly[i+131071];
-for(int i=offset-1-65536;i>=offset-131070;--i)poly[i]^=poly[i+131070]^poly[i+131071];
-for(int i=offset-1-131070;i>=offset-131071;--i)poly[i]^=poly[i+131071];
-
-}
-for(int offset=(1<<16);offset<(1<=offset+(1<<16)-65536;--i)poly[i]^=poly[i+65535];
-for(int i=offset-1-0;i>=offset-65535;--i)poly[i]^=poly[i+65535];
-
-}
-}
-static
-void bc_to_lch_256_16(__m256i* poly, int logn){
-for(int offset=(1<<15);offset<(1<=offset+(1<<15)-24576;--i)poly[i]^=poly[i+16384];
-for(int i=offset+(1<<15)-1-24576;i>=offset+(1<<15)-28672;--i)poly[i]^=poly[i+16384]^poly[i+24576];
-for(int i=offset+(1<<15)-1-28672;i>=offset+(1<<15)-30720;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672];
-for(int i=offset+(1<<15)-1-30720;i>=offset+(1<<15)-31744;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720];
-for(int i=offset+(1<<15)-1-31744;i>=offset+(1<<15)-32256;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744];
-for(int i=offset+(1<<15)-1-32256;i>=offset+(1<<15)-32512;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256];
-for(int i=offset+(1<<15)-1-32512;i>=offset+(1<<15)-32640;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512];
-for(int i=offset+(1<<15)-1-32640;i>=offset+(1<<15)-32704;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640];
-for(int i=offset+(1<<15)-1-32704;i>=offset+(1<<15)-32736;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704];
-for(int i=offset+(1<<15)-1-32736;i>=offset+(1<<15)-32752;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736];
-for(int i=offset+(1<<15)-1-32752;i>=offset+(1<<15)-32760;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752];
-for(int i=offset+(1<<15)-1-32760;i>=offset+(1<<15)-32764;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760];
-for(int i=offset+(1<<15)-1-32764;i>=offset+(1<<15)-32766;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764];
-for(int i=offset+(1<<15)-1-32766;i>=offset+(1<<15)-32767;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766];
-for(int i=offset+(1<<15)-1-32767;i>=offset+(1<<15)-32768;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-0;i>=offset-16384;--i)poly[i]^=poly[i+16384]^poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-16384;i>=offset-24576;--i)poly[i]^=poly[i+24576]^poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-24576;i>=offset-28672;--i)poly[i]^=poly[i+28672]^poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-28672;i>=offset-30720;--i)poly[i]^=poly[i+30720]^poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-30720;i>=offset-31744;--i)poly[i]^=poly[i+31744]^poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-31744;i>=offset-32256;--i)poly[i]^=poly[i+32256]^poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32256;i>=offset-32512;--i)poly[i]^=poly[i+32512]^poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32512;i>=offset-32640;--i)poly[i]^=poly[i+32640]^poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32640;i>=offset-32704;--i)poly[i]^=poly[i+32704]^poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32704;i>=offset-32736;--i)poly[i]^=poly[i+32736]^poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32736;i>=offset-32752;--i)poly[i]^=poly[i+32752]^poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32752;i>=offset-32760;--i)poly[i]^=poly[i+32760]^poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32760;i>=offset-32764;--i)poly[i]^=poly[i+32764]^poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32764;i>=offset-32766;--i)poly[i]^=poly[i+32766]^poly[i+32767];
-for(int i=offset-1-32766;i>=offset-32767;--i)poly[i]^=poly[i+32767];
-
-}
-for(int offset=(1<<14);offset<(1<=offset+(1<<14)-15360;--i)poly[i]^=poly[i+12288];
-for(int i=offset+(1<<14)-1-15360;i>=offset+(1<<14)-16128;--i)poly[i]^=poly[i+12288]^poly[i+15360];
-for(int i=offset+(1<<14)-1-16128;i>=offset+(1<<14)-16320;--i)poly[i]^=poly[i+12288]^poly[i+15360]^poly[i+16128];
-for(int i=offset+(1<<14)-1-16320;i>=offset+(1<<14)-16368;--i)poly[i]^=poly[i+12288]^poly[i+15360]^poly[i+16128]^poly[i+16320];
-for(int i=offset+(1<<14)-1-16368;i>=offset+(1<<14)-16380;--i)poly[i]^=poly[i+12288]^poly[i+15360]^poly[i+16128]^poly[i+16320]^poly[i+16368];
-for(int i=offset+(1<<14)-1-16380;i>=offset+(1<<14)-16383;--i)poly[i]^=poly[i+12288]^poly[i+15360]^poly[i+16128]^poly[i+16320]^poly[i+16368]^poly[i+16380];
-for(int i=offset+(1<<14)-1-16383;i>=offset+(1<<14)-16384;--i)poly[i]^=poly[i+12288]^poly[i+15360]^poly[i+16128]^poly[i+16320]^poly[i+16368]^poly[i+16380]^poly[i+16383];
-for(int i=offset-1-0;i>=offset-12288;--i)poly[i]^=poly[i+12288]^poly[i+15360]^poly[i+16128]^poly[i+16320]^poly[i+16368]^poly[i+16380]^poly[i+16383];
-for(int i=offset-1-12288;i>=offset-15360;--i)poly[i]^=poly[i+15360]^poly[i+16128]^poly[i+16320]^poly[i+16368]^poly[i+16380]^poly[i+16383];
-for(int i=offset-1-15360;i>=offset-16128;--i)poly[i]^=poly[i+16128]^poly[i+16320]^poly[i+16368]^poly[i+16380]^poly[i+16383];
-for(int i=offset-1-16128;i>=offset-16320;--i)poly[i]^=poly[i+16320]^poly[i+16368]^poly[i+16380]^poly[i+16383];
-for(int i=offset-1-16320;i>=offset-16368;--i)poly[i]^=poly[i+16368]^poly[i+16380]^poly[i+16383];
-for(int i=offset-1-16368;i>=offset-16380;--i)poly[i]^=poly[i+16380]^poly[i+16383];
-for(int i=offset-1-16380;i>=offset-16383;--i)poly[i]^=poly[i+16383];
-
-}
-for(int offset=(1<<13);offset<(1<=offset+(1<<13)-7680;--i)poly[i]^=poly[i+4096];
-for(int i=offset+(1<<13)-1-7680;i>=offset+(1<<13)-7936;--i)poly[i]^=poly[i+4096]^poly[i+7680];
-for(int i=offset+(1<<13)-1-7936;i>=offset+(1<<13)-8160;--i)poly[i]^=poly[i+4096]^poly[i+7680]^poly[i+7936];
-for(int i=offset+(1<<13)-1-8160;i>=offset+(1<<13)-8176;--i)poly[i]^=poly[i+4096]^poly[i+7680]^poly[i+7936]^poly[i+8160];
-for(int i=offset+(1<<13)-1-8176;i>=offset+(1<<13)-8190;--i)poly[i]^=poly[i+4096]^poly[i+7680]^poly[i+7936]^poly[i+8160]^poly[i+8176];
-for(int i=offset+(1<<13)-1-8190;i>=offset+(1<<13)-8191;--i)poly[i]^=poly[i+4096]^poly[i+7680]^poly[i+7936]^poly[i+8160]^poly[i+8176]^poly[i+8190];
-for(int i=offset+(1<<13)-1-8191;i>=offset+(1<<13)-8192;--i)poly[i]^=poly[i+4096]^poly[i+7680]^poly[i+7936]^poly[i+8160]^poly[i+8176]^poly[i+8190]^poly[i+8191];
-for(int i=offset-1-0;i>=offset-4096;--i)poly[i]^=poly[i+4096]^poly[i+7680]^poly[i+7936]^poly[i+8160]^poly[i+8176]^poly[i+8190]^poly[i+8191];
-for(int i=offset-1-4096;i>=offset-7680;--i)poly[i]^=poly[i+7680]^poly[i+7936]^poly[i+8160]^poly[i+8176]^poly[i+8190]^poly[i+8191];
-for(int i=offset-1-7680;i>=offset-7936;--i)poly[i]^=poly[i+7936]^poly[i+8160]^poly[i+8176]^poly[i+8190]^poly[i+8191];
-for(int i=offset-1-7936;i>=offset-8160;--i)poly[i]^=poly[i+8160]^poly[i+8176]^poly[i+8190]^poly[i+8191];
-for(int i=offset-1-8160;i>=offset-8176;--i)poly[i]^=poly[i+8176]^poly[i+8190]^poly[i+8191];
-for(int i=offset-1-8176;i>=offset-8190;--i)poly[i]^=poly[i+8190]^poly[i+8191];
-for(int i=offset-1-8190;i>=offset-8191;--i)poly[i]^=poly[i+8191];
-
-}
-for(int offset=(1<<12);offset<(1<=offset+(1<<12)-4080;--i)poly[i]^=poly[i+3840];
-for(int i=offset+(1<<12)-1-4080;i>=offset+(1<<12)-4095;--i)poly[i]^=poly[i+3840]^poly[i+4080];
-for(int i=offset+(1<<12)-1-4095;i>=offset+(1<<12)-4096;--i)poly[i]^=poly[i+3840]^poly[i+4080]^poly[i+4095];
-for(int i=offset-1-0;i>=offset-3840;--i)poly[i]^=poly[i+3840]^poly[i+4080]^poly[i+4095];
-for(int i=offset-1-3840;i>=offset-4080;--i)poly[i]^=poly[i+4080]^poly[i+4095];
-for(int i=offset-1-4080;i>=offset-4095;--i)poly[i]^=poly[i+4095];
-
-}
-for(int offset=(1<<11);offset<(1<=offset+(1<<11)-1536;--i)poly[i]^=poly[i+1024];
-for(int i=offset+(1<<11)-1-1536;i>=offset+(1<<11)-1792;--i)poly[i]^=poly[i+1024]^poly[i+1536];
-for(int i=offset+(1<<11)-1-1792;i>=offset+(1<<11)-2040;--i)poly[i]^=poly[i+1024]^poly[i+1536]^poly[i+1792];
-for(int i=offset+(1<<11)-1-2040;i>=offset+(1<<11)-2044;--i)poly[i]^=poly[i+1024]^poly[i+1536]^poly[i+1792]^poly[i+2040];
-for(int i=offset+(1<<11)-1-2044;i>=offset+(1<<11)-2046;--i)poly[i]^=poly[i+1024]^poly[i+1536]^poly[i+1792]^poly[i+2040]^poly[i+2044];
-for(int i=offset+(1<<11)-1-2046;i>=offset+(1<<11)-2047;--i)poly[i]^=poly[i+1024]^poly[i+1536]^poly[i+1792]^poly[i+2040]^poly[i+2044]^poly[i+2046];
-for(int i=offset+(1<<11)-1-2047;i>=offset+(1<<11)-2048;--i)poly[i]^=poly[i+1024]^poly[i+1536]^poly[i+1792]^poly[i+2040]^poly[i+2044]^poly[i+2046]^poly[i+2047];
-for(int i=offset-1-0;i>=offset-1024;--i)poly[i]^=poly[i+1024]^poly[i+1536]^poly[i+1792]^poly[i+2040]^poly[i+2044]^poly[i+2046]^poly[i+2047];
-for(int i=offset-1-1024;i>=offset-1536;--i)poly[i]^=poly[i+1536]^poly[i+1792]^poly[i+2040]^poly[i+2044]^poly[i+2046]^poly[i+2047];
-for(int i=offset-1-1536;i>=offset-1792;--i)poly[i]^=poly[i+1792]^poly[i+2040]^poly[i+2044]^poly[i+2046]^poly[i+2047];
-for(int i=offset-1-1792;i>=offset-2040;--i)poly[i]^=poly[i+2040]^poly[i+2044]^poly[i+2046]^poly[i+2047];
-for(int i=offset-1-2040;i>=offset-2044;--i)poly[i]^=poly[i+2044]^poly[i+2046]^poly[i+2047];
-for(int i=offset-1-2044;i>=offset-2046;--i)poly[i]^=poly[i+2046]^poly[i+2047];
-for(int i=offset-1-2046;i>=offset-2047;--i)poly[i]^=poly[i+2047];
-
-}
-for(int offset=(1<<10);offset<(1<=offset+(1<<10)-1020;--i)poly[i]^=poly[i+768];
-for(int i=offset+(1<<10)-1-1020;i>=offset+(1<<10)-1023;--i)poly[i]^=poly[i+768]^poly[i+1020];
-for(int i=offset+(1<<10)-1-1023;i>=offset+(1<<10)-1024;--i)poly[i]^=poly[i+768]^poly[i+1020]^poly[i+1023];
-for(int i=offset-1-0;i>=offset-768;--i)poly[i]^=poly[i+768]^poly[i+1020]^poly[i+1023];
-for(int i=offset-1-768;i>=offset-1020;--i)poly[i]^=poly[i+1020]^poly[i+1023];
-for(int i=offset-1-1020;i>=offset-1023;--i)poly[i]^=poly[i+1023];
-
-}
-for(int offset=(1<<9);offset<(1<=offset+(1<<9)-510;--i)poly[i]^=poly[i+256];
-for(int i=offset+(1<<9)-1-510;i>=offset+(1<<9)-511;--i)poly[i]^=poly[i+256]^poly[i+510];
-for(int i=offset+(1<<9)-1-511;i>=offset+(1<<9)-512;--i)poly[i]^=poly[i+256]^poly[i+510]^poly[i+511];
-for(int i=offset-1-0;i>=offset-256;--i)poly[i]^=poly[i+256]^poly[i+510]^poly[i+511];
-for(int i=offset-1-256;i>=offset-510;--i)poly[i]^=poly[i+510]^poly[i+511];
-for(int i=offset-1-510;i>=offset-511;--i)poly[i]^=poly[i+511];
-
-}
-for(int offset=(1<<8);offset<(1<=offset+(1<<8)-256;--i)poly[i]^=poly[i+255];
-for(int i=offset-1-0;i>=offset-255;--i)poly[i]^=poly[i+255];
-
-}
-for(int offset=(1<<7);offset<(1<=offset+(1<<7)-96;--i)poly[i]^=poly[i+64];
-for(int i=offset+(1<<7)-1-96;i>=offset+(1<<7)-112;--i)poly[i]^=poly[i+64]^poly[i+96];
-for(int i=offset+(1<<7)-1-112;i>=offset+(1<<7)-120;--i)poly[i]^=poly[i+64]^poly[i+96]^poly[i+112];
-for(int i=offset+(1<<7)-1-120;i>=offset+(1<<7)-124;--i)poly[i]^=poly[i+64]^poly[i+96]^poly[i+112]^poly[i+120];
-for(int i=offset+(1<<7)-1-124;i>=offset+(1<<7)-126;--i)poly[i]^=poly[i+64]^poly[i+96]^poly[i+112]^poly[i+120]^poly[i+124];
-for(int i=offset+(1<<7)-1-126;i>=offset+(1<<7)-127;--i)poly[i]^=poly[i+64]^poly[i+96]^poly[i+112]^poly[i+120]^poly[i+124]^poly[i+126];
-for(int i=offset+(1<<7)-1-127;i>=offset+(1<<7)-128;--i)poly[i]^=poly[i+64]^poly[i+96]^poly[i+112]^poly[i+120]^poly[i+124]^poly[i+126]^poly[i+127];
-for(int i=offset-1-0;i>=offset-64;--i)poly[i]^=poly[i+64]^poly[i+96]^poly[i+112]^poly[i+120]^poly[i+124]^poly[i+126]^poly[i+127];
-for(int i=offset-1-64;i>=offset-96;--i)poly[i]^=poly[i+96]^poly[i+112]^poly[i+120]^poly[i+124]^poly[i+126]^poly[i+127];
-for(int i=offset-1-96;i>=offset-112;--i)poly[i]^=poly[i+112]^poly[i+120]^poly[i+124]^poly[i+126]^poly[i+127];
-for(int i=offset-1-112;i>=offset-120;--i)poly[i]^=poly[i+120]^poly[i+124]^poly[i+126]^poly[i+127];
-for(int i=offset-1-120;i>=offset-124;--i)poly[i]^=poly[i+124]^poly[i+126]^poly[i+127];
-for(int i=offset-1-124;i>=offset-126;--i)poly[i]^=poly[i+126]^poly[i+127];
-for(int i=offset-1-126;i>=offset-127;--i)poly[i]^=poly[i+127];
-
-}
-for(int offset=(1<<6);offset<(1<=offset+(1<<6)-60;--i)poly[i]^=poly[i+48];
-for(int i=offset+(1<<6)-1-60;i>=offset+(1<<6)-63;--i)poly[i]^=poly[i+48]^poly[i+60];
-for(int i=offset+(1<<6)-1-63;i>=offset+(1<<6)-64;--i)poly[i]^=poly[i+48]^poly[i+60]^poly[i+63];
-for(int i=offset-1-0;i>=offset-48;--i)poly[i]^=poly[i+48]^poly[i+60]^poly[i+63];
-for(int i=offset-1-48;i>=offset-60;--i)poly[i]^=poly[i+60]^poly[i+63];
-for(int i=offset-1-60;i>=offset-63;--i)poly[i]^=poly[i+63];
-
-}
-for(int offset=(1<<5);offset<(1<=offset+(1<<5)-30;--i)poly[i]^=poly[i+16];
-for(int i=offset+(1<<5)-1-30;i>=offset+(1<<5)-31;--i)poly[i]^=poly[i+16]^poly[i+30];
-for(int i=offset+(1<<5)-1-31;i>=offset+(1<<5)-32;--i)poly[i]^=poly[i+16]^poly[i+30]^poly[i+31];
-for(int i=offset-1-0;i>=offset-16;--i)poly[i]^=poly[i+16]^poly[i+30]^poly[i+31];
-for(int i=offset-1-16;i>=offset-30;--i)poly[i]^=poly[i+30]^poly[i+31];
-for(int i=offset-1-30;i>=offset-31;--i)poly[i]^=poly[i+31];
-
-}
-for(int offset=(1<<4);offset<(1<=offset+(1<<4)-16;--i)poly[i]^=poly[i+15];
-for(int i=offset-1-0;i>=offset-15;--i)poly[i]^=poly[i+15];
-
-}
-for(int offset=(1<<3);offset<(1<=offset+(1<<3)-6;--i)poly[i]^=poly[i+4];
-for(int i=offset+(1<<3)-1-6;i>=offset+(1<<3)-7;--i)poly[i]^=poly[i+4]^poly[i+6];
-for(int i=offset+(1<<3)-1-7;i>=offset+(1<<3)-8;--i)poly[i]^=poly[i+4]^poly[i+6]^poly[i+7];
-for(int i=offset-1-0;i>=offset-4;--i)poly[i]^=poly[i+4]^poly[i+6]^poly[i+7];
-for(int i=offset-1-4;i>=offset-6;--i)poly[i]^=poly[i+6]^poly[i+7];
-for(int i=offset-1-6;i>=offset-7;--i)poly[i]^=poly[i+7];
-
-}
-for(int offset=(1<<2);offset<(1<=offset+(1<<2)-4;--i)poly[i]^=poly[i+3];
-for(int i=offset-1-0;i>=offset-3;--i)poly[i]^=poly[i+3];
-
-}
-for(int offset=(1<<1);offset<(1<=offset+(1<<1)-2;--i)poly[i]^=poly[i+1];
-for(int i=offset-1-0;i>=offset-1;--i)poly[i]^=poly[i+1];
-
-}
-}
diff --git a/bc_to_mono_gen_code.c b/bc_to_mono_gen_code.c
deleted file mode 100644
index 745a414..0000000
--- a/bc_to_mono_gen_code.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
-Copyright (C) 2018 Wen-Ding Li
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-void bc_to_mono_256_16(__m256i* poly, int logn){
-for(int offset=(1<<1);offset<(1<
-#include
-#include
-#include
-
-/* #define CONFIG_BENCH_SYSTIME */
-
-#define CONFIG_BENCH_SYSTIME
-
-#if defined(CONFIG_BENCH_SYSTIME)
-#include
-#endif
-
-/* Copied from http://en.wikipedia.org/wiki/RDTSC */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-#if !defined(CONFIG_BENCH_SYSTIME)
-#if defined(CONFIG_NEON)
-static inline uint32_t
-rdtsc32(void)
-{
-#if defined(__GNUC__) && defined(__ARM_ARCH_7A__)
- uint32_t r = 0;
- asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(r) );
- return r;
-#else
-#error Unsupported architecture/compiler!
-#endif
-}
-#else
-static inline uint64_t rdtsc() {
- uint32_t lo, hi;
- /* We cannot use "=A", since this would use %rax on x86_64 */
- __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
- return (uint64_t)hi << 32 | lo;
-}
-#endif
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#define RECMAX 6
-
-#define BENCHMARK(bm,call) do { \
- bm_start(&(bm)); \
- call; \
- bm_stop(&(bm)); \
- } while (0)
-
-struct benchmark {
-#if defined(CONFIG_BENCH_SYSTIME)
- struct timeval start;
- struct timeval stop;
-#else
- uint64_t start;
- uint64_t stop;
-#endif
- double record[RECMAX];
- double acc;
- int currec;
- int count;
-};
-
-static inline void
-bm_init(struct benchmark *bm)
-{
- memset(bm, 0, sizeof(*bm));
-}
-
-static inline void
-bm_start(struct benchmark *bm)
-{
-#if defined(CONFIG_BENCH_SYSTIME)
- gettimeofday(& bm->start , NULL);
-#else
-#if defined(CONFIG_NEON)
- bm->start = rdtsc32();
-#else
- bm->start = rdtsc();
-#endif
-#endif
-}
-
-static inline void
-bm_stop(struct benchmark *bm)
-{
-#if defined(CONFIG_BENCH_SYSTIME)
- gettimeofday(& bm->stop , NULL);
- bm->record[bm->currec] = (bm->stop.tv_sec - bm->start.tv_sec)*1000000.0; /* sec to us */
- bm->record[bm->currec] += bm->stop.tv_usec - bm->start.tv_usec;
-#else
-#if defined(CONFIG_NEON)
- bm->stop = rdtsc32();
-#else
- bm->stop = rdtsc();
-#endif
- bm->record[bm->currec] = bm->stop - bm->start;
-#endif
- bm->acc += bm->record[bm->currec];
- bm->currec = (bm->currec + 1) % RECMAX;
- ++bm->count;
-}
-
-static inline void
-bm_dump(char *buf, size_t bufsize, const struct benchmark *bm)
-{
- int i;
- size_t len;
-#if defined(CONFIG_BENCH_SYSTIME)
- const char * unit = "micro sec.";
-#else
- const char * unit = "cycles";
-#endif
-
- len = snprintf(buf, bufsize, "%.0lf (%s, avg. of %d):", bm->acc/bm->count, unit, bm->count);
- buf += len;
- bufsize -= len;
- for (i = 0; i < RECMAX; ++i) {
- len = snprintf(buf, bufsize, " %.0lf", bm->record[i]);
- buf += len;
- bufsize -= len;
- }
-}
-
-#endif /* BENCHMARK_H */
diff --git a/bitmat_prod.h b/bitmat_prod.h
deleted file mode 100644
index 817111f..0000000
--- a/bitmat_prod.h
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#ifndef _BITMAT_PROD_H_
-#define _BITMAT_PROD_H_
-
-#include
-#include
-#include
-
-static inline
-__m128i bitmat_prod_accu_64x128_M4R_sse( __m128i r0 , const uint64_t * mat4R , uint64_t a )
-{
- const __m128i * mat128 = (const __m128i*)mat4R;
- while( a ) {
- r0 ^= _mm_load_si128( mat128 + (a&0xf) );
- mat128 += 16;
- a >>= 4;
- }
- return r0;
-}
-
-static inline
-void bitmatrix_prod_64x128_4R_sse( uint8_t * r , const uint64_t * mat4R , uint64_t a )
-{
- __m128i r0 = _mm_setzero_si128();
- r0 = bitmat_prod_accu_64x128_M4R_sse( r0 , mat4R , a );
- _mm_store_si128( (__m128i *) r , r0 );
-}
-
-static inline
-void bitmatrix_prod_128x128_4R_sse( uint8_t * r , const uint64_t * mat4R , const uint8_t *a )
-{
- __m128i r0 = _mm_setzero_si128();
- const uint64_t *a64 = (const uint64_t*)a;
- r0 = bitmat_prod_accu_64x128_M4R_sse( r0 , mat4R , a64[0] );
- r0 = bitmat_prod_accu_64x128_M4R_sse( r0 , mat4R+2*256 , a64[1] );
- _mm_store_si128( (__m128i *) r , r0 );
-}
-
-
-
-static inline
-__m256i bitmat_prod_accu_64x256_M4R_avx( __m256i r0 , const uint64_t * mat4R , uint64_t a )
-{
- const __m256i * mat256 = (const __m256i*)mat4R;
- while( a ) {
- r0 ^= _mm256_load_si256( mat256 + (a&0xf) );
- mat256 += 16;
- a >>= 4;
- }
- return r0;
-}
-
-
-static inline
-__m256i bitmat_prod_128x128_x2_4R_sse( const uint64_t * mat4R , __m256i a )
-{
- uint64_t a64[4] __attribute__((aligned(32)));
- _mm256_store_si256( (__m256i*) a64 , a );
-
- __m128i r0 = _mm_setzero_si128();
- __m128i r1 = _mm_setzero_si128();
- r0 = bitmat_prod_accu_64x128_M4R_sse( r0 , mat4R , a64[0] );
- r1 = bitmat_prod_accu_64x128_M4R_sse( r1 , mat4R , a64[2] );
- r0 = bitmat_prod_accu_64x128_M4R_sse( r0 , mat4R+2*256 , a64[1] );
- r1 = bitmat_prod_accu_64x128_M4R_sse( r1 , mat4R+2*256 , a64[3] );
-
- __m256i r = _mm256_castsi128_si256( r0 );
- return _mm256_inserti128_si256( r , r1 , 1 );
-}
-
-
-
-static inline
-void bitmatrix_prod_128x256_4R_avx( uint8_t * r , const uint64_t * mat4R , const uint64_t *a )
-{
- __m256i r0 = _mm256_setzero_si256();
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R , a[0] );
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R+16*16*4 , a[1] );
- _mm256_store_si256( (__m256i *) r , r0 );
-}
-
-static inline
-void bitmatrix_prod_256x256_4R_avx( uint8_t * r , const uint64_t * mat4R , const uint64_t *a )
-{
- __m256i r0 = _mm256_setzero_si256();
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R , a[0] );
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R+16*16*4 , a[1] );
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R+16*16*4*2 , a[2] );
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R+16*16*4*3 , a[3] );
- _mm256_store_si256( (__m256i *) r , r0 );
-}
-
-
-static inline
-void bitmatrix_prod_tri256x256_4R_avx( uint8_t * r , const uint64_t * mat4R_128 , const uint64_t * mat4R_256h , const uint64_t *a )
-{
- __m128i r0_128 = _mm_setzero_si128();
- r0_128 = bitmat_prod_accu_64x128_M4R_sse( r0_128 , mat4R_128 , a[0] );
- r0_128 = bitmat_prod_accu_64x128_M4R_sse( r0_128 , mat4R_128+2*256 , a[1] );
-
- __m256i r0 = _mm256_inserti128_si256( _mm256_setzero_si256() , r0_128 , 0 );
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R_256h , a[2] );
- r0 = bitmat_prod_accu_64x256_M4R_avx( r0 , mat4R_256h+16*16*4 , a[3] );
- _mm256_store_si256( (__m256i *) r , r0 );
-}
-
-
-
-
-static inline
-__m128i bitmat_prod_accu_64x128_M6R_sse( __m128i r0 , const uint64_t * mat4R , uint64_t a )
-{
- const __m128i * mat128 = (const __m128i*)mat4R;
- while( a ) {
- r0 ^= _mm_load_si128( mat128 + (a&0x3f) );
- mat128 += 64;
- a >>= 6;
- }
- return r0;
-}
-
-static inline
-void bitmatrix_prod_64x128_6R_sse( uint8_t * r , const uint64_t * mat4R , uint64_t a )
-{
- __m128i r0 = _mm_setzero_si128();
- r0 = bitmat_prod_accu_64x128_M6R_sse( r0 , mat4R , a );
- _mm_store_si128( (__m128i *) r , r0 );
-}
-
-static inline
-void bitmatrix_prod_128x128_6R_sse( uint8_t * r , const uint64_t * mat4R , const uint8_t *a )
-{
- __m128i r0 = _mm_setzero_si128();
- const uint64_t *a64 = (const uint64_t*)a;
- r0 = bitmat_prod_accu_64x128_M6R_sse( r0 , mat4R , a64[0] );
- r0 = bitmat_prod_accu_64x128_M6R_sse( r0 , mat4R+2*64*11 , a64[1] );
- _mm_store_si128( (__m128i *) r , r0 );
-}
-
-
-
-
-static inline
-__m128i bitmat_prod_accu_64x128_M8R_sse( __m128i r0 , const uint64_t * mat4R , uint64_t a )
-{
- const __m128i * mat128 = (const __m128i*)mat4R;
- while( a ) {
- r0 ^= _mm_load_si128( mat128 + (a&0xff) );
- mat128 += 256;
- a >>= 8;
- }
- return r0;
-}
-
-static inline
-void bitmatrix_prod_64x128_8R_sse( uint8_t * r , const uint64_t * mat4R , uint64_t a )
-{
- __m128i r0 = _mm_setzero_si128();
- r0 = bitmat_prod_accu_64x128_M8R_sse( r0 , mat4R , a );
- _mm_store_si128( (__m128i *) r , r0 );
-}
-
-static inline
-void bitmatrix_prod_128x128_8R_sse( uint8_t * r , const uint64_t * mat4R , const uint8_t *a )
-{
- __m128i r0 = _mm_setzero_si128();
- const uint64_t *a64 = (const uint64_t*)a;
- r0 = bitmat_prod_accu_64x128_M8R_sse( r0 , mat4R , a64[0] );
- r0 = bitmat_prod_accu_64x128_M8R_sse( r0 , mat4R+2*256*8 , a64[1] );
- _mm_store_si128( (__m128i *) r , r0 );
-}
-
-
-
-#include "transpose.h"
-
-
-static inline
-void bitmatrix_prod_128x128_4R_b32_avx2( uint8_t * r32 , const uint64_t * matB4R , const uint8_t *a32 )
-{
- uint8_t t32[32*16] __attribute__((aligned(32)));
- tr_16x16_b2_avx2( t32 , a32 );
-
- __m256i *r = (__m256i*) r32;
- const __m256i * tab = (const __m256i*) & matB4R[0];
- __m256i _0xf = _mm256_set1_epi8(0xf);
-
- for(unsigned i=0;i<16;i++) r[i] = _mm256_setzero_si256();
-
-for(unsigned k=0;k<16;k+=8) {
- for(unsigned i=0;i<16;i++) {
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i low1_low0 = temp&_0xf;
- __m256i high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- __m256i high1_low0 = _mm256_permute2x128_si256( low1_low0 , high1_high0 , 0x30 );
- __m256i low1_high0 = _mm256_permute2x128_si256( low1_low0 , high1_high0 , 0x12);
-
- for(unsigned j=k;j>= 4;
- }
- return r;
-}
-
-
-static inline
-void mat_mul_64x64_64x64_m4r( uint64_t * r , const uint64_t *mat4r , uint64_t * a )
-{
- for(unsigned i=0;i<64;i++) r[i] = bitmatrix_prod_64x64_M4R( mat4r , a[i] );
-}
-
-static inline
-uint64_t bitmatrix_prod_64x64_M8R( const uint64_t * mat4r , uint64_t a )
-{
- uint64_t r = 0;
- while( a ) {
- r ^= mat4r[ a&0xff ];
- mat4r += 256;
- a >>= 8;
- }
- return r;
-}
-
-static inline
-void mat_mul_64x64_64x64_m8r( uint64_t * r , const uint64_t *mat4r , uint64_t * a )
-{
- for(unsigned i=0;i<64;i++) r[i] = bitmatrix_prod_64x64_M8R( mat4r , a[i] );
-}
-
-
-static inline
-void bitmatrix_prod_64x64_4R_b32_avx2( uint8_t * r128_32 , const uint64_t * matB4R , const uint8_t *a64_32 )
-{
- uint8_t t32[32*8] __attribute__((aligned(32)));
- /// 0x10,0x11,0x12,.....0x2f
- transpose_8x8_b4_avx2( t32 , a64_32 );
- /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, |
- /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f,
-
- __m256i *r = (__m256i*) r128_32;
- const __m256i * tab = (const __m256i*) & matB4R[0];
- __m256i _0xf = _mm256_set1_epi8(0xf);
-
- for(unsigned i=0;i<8;i++) r[i] = _mm256_setzero_si256();
- for(unsigned i=0;i<8;i++) { ///
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i low1_low0 = temp&_0xf;
- __m256i high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- for(unsigned j=0;j<8;j++) {
- __m256i tab_0 = tab[i*16+j*2];
- __m256i tab_1 = tab[i*16+j*2+1];
- r[j] ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- }
- }
-
- transpose_8x8_b4_avx2( r128_32 , r128_32 );
-}
-
-static inline
-void bitmatrix_prod_64x64_4R_b64_avx2( uint8_t * r128_32 , const uint64_t * matB4R , const uint8_t *a64_32 )
-{
-#if 0
- bitmatrix_prod_64x64_4R_b32_avx2( r128_32 , matB4R , a64_32 );
- bitmatrix_prod_64x64_4R_b32_avx2( r128_32+8*32 , matB4R , a64_32+8*32 );
-#else
- uint8_t t32[32*8] __attribute__((aligned(32)));
- uint8_t u32[32*8] __attribute__((aligned(32)));
-
- /// 0x10,0x11,0x12,.....0x2f
- transpose_8x8_b4_avx2( t32 , a64_32 );
- transpose_8x8_b4_avx2( u32 , a64_32+8*32 );
- /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, |
- /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f,
-
- const __m256i * tab = (const __m256i*) & matB4R[0];
- __m256i _0xf = _mm256_set1_epi8(0xf);
-
- __m256i r0 = _mm256_setzero_si256();
- __m256i r1 = _mm256_setzero_si256();
- __m256i r2 = _mm256_setzero_si256();
- __m256i r3 = _mm256_setzero_si256();
- __m256i r4 = _mm256_setzero_si256();
- __m256i r5 = _mm256_setzero_si256();
- __m256i r6 = _mm256_setzero_si256();
- __m256i r7 = _mm256_setzero_si256();
- for(unsigned i=0;i<8;i++) { ///
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i _0_low1_low0 = temp&_0xf;
- __m256i _0_high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- __m256i temp1 = _mm256_load_si256( (__m256i*)(u32 + i*32) );
- __m256i _1_low1_low0 = temp1&_0xf;
- __m256i _1_high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp1 ) , 4 );
-
- __m256i tab_0 = tab[i*16];
- __m256i tab_1 = tab[i*16+1];
- r0 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r4 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- tab_0 = tab[i*16+2];
- tab_1 = tab[i*16+3];
- r1 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r5 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- tab_0 = tab[i*16+4];
- tab_1 = tab[i*16+5];
- r2 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r6 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- tab_0 = tab[i*16+6];
- tab_1 = tab[i*16+7];
- r3 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r7 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- }
- _mm256_store_si256( (__m256i*)(r128_32+0) , r0 );
- _mm256_store_si256( (__m256i*)(r128_32+1*32) , r1 );
- _mm256_store_si256( (__m256i*)(r128_32+2*32) , r2 );
- _mm256_store_si256( (__m256i*)(r128_32+3*32) , r3 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+0*32) , r4 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+1*32) , r5 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+2*32) , r6 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+3*32) , r7 );
-
- r0 = _mm256_setzero_si256();
- r1 = _mm256_setzero_si256();
- r2 = _mm256_setzero_si256();
- r3 = _mm256_setzero_si256();
- r4 = _mm256_setzero_si256();
- r5 = _mm256_setzero_si256();
- r6 = _mm256_setzero_si256();
- r7 = _mm256_setzero_si256();
- for(unsigned i=0;i<8;i++) { ///
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i _0_low1_low0 = temp&_0xf;
- __m256i _0_high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- __m256i temp1 = _mm256_load_si256( (__m256i*)(u32 + i*32) );
- __m256i _1_low1_low0 = temp1&_0xf;
- __m256i _1_high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp1 ) , 4 );
-
- __m256i tab_0 = tab[i*16+8];
- __m256i tab_1 = tab[i*16+8+1];
- r0 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r4 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- tab_0 = tab[i*16+8+2];
- tab_1 = tab[i*16+8+3];
- r1 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r5 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- tab_0 = tab[i*16+8+4];
- tab_1 = tab[i*16+8+5];
- r2 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r6 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- tab_0 = tab[i*16+8+6];
- tab_1 = tab[i*16+8+7];
- r3 ^= _mm256_shuffle_epi8( tab_0 , _0_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _0_high1_high0 );
- r7 ^= _mm256_shuffle_epi8( tab_0 , _1_low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _1_high1_high0 );
- }
- _mm256_store_si256( (__m256i*)(r128_32+4*32+0) , r0 );
- _mm256_store_si256( (__m256i*)(r128_32+4*32+1*32) , r1 );
- _mm256_store_si256( (__m256i*)(r128_32+4*32+2*32) , r2 );
- _mm256_store_si256( (__m256i*)(r128_32+4*32+3*32) , r3 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+0*32) , r4 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+1*32) , r5 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+2*32) , r6 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+3*32) , r7 );
-
- transpose_8x8_b4_avx2( r128_32 , r128_32 );
- transpose_8x8_b4_avx2( r128_32+8*32 , r128_32+8*32 );
-#endif
-}
-
-
-static inline
-void mat_mul_64x64_64x64_m4r_avx2( uint8_t * r , const uint64_t *mat4r , uint8_t * a )
-{
- bitmatrix_prod_64x64_4R_b32_avx2( r , mat4r , a );
- bitmatrix_prod_64x64_4R_b32_avx2( r+8*32 , mat4r , a+8*32 );
-}
-
-
-static inline
-void bitmatrix_prod_64x64_h32zero_4R_b32_avx2( uint8_t * r128_32 , const uint64_t * matB4R , const uint8_t *a64_32 )
-{
- uint8_t t32[32*4] __attribute__((aligned(32)));
- /// 0x10,0x11,0x12,.....0x2f
- transpose_8x8_h4zero_b4_avx2( t32 , a64_32 );
- /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, |
- /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f,
-
- __m256i *r = (__m256i*) r128_32;
- const __m256i * tab = (const __m256i*) & matB4R[0];
- __m256i _0xf = _mm256_set1_epi8(0xf);
-
- for(unsigned i=0;i<8;i++) r[i] = _mm256_setzero_si256();
- for(unsigned i=0;i<4;i++) { ///
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i low1_low0 = temp&_0xf;
- __m256i high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- for(unsigned j=0;j<8;j++) {
- __m256i tab_0 = tab[i*16+j*2];
- __m256i tab_1 = tab[i*16+j*2+1];
- r[j] ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- }
- }
-
- transpose_8x8_b4_avx2( r128_32 , r128_32 );
-}
-
-
-static inline
-void bitmatrix_prod_64x64_h32zero_4R_b64_avx2( uint8_t * r128_32 , const uint64_t * matB4R , const uint8_t *a64_32 )
-{
- uint8_t t32[32*8] __attribute__((aligned(32)));
- transpose_8x8_h4zero_b4_avx2( t32 , a64_32 );
- transpose_8x8_h4zero_b4_avx2( t32+32*4 , a64_32+32*8 );
-
- const __m256i * tab = (const __m256i*) & matB4R[0];
- __m256i _0xf = _mm256_set1_epi8(0xf);
-
- __m256i r0,r1,r2,r3,r4,r5,r6,r7;
- r0 = _mm256_setzero_si256();
- r1 = _mm256_setzero_si256();
- r2 = _mm256_setzero_si256();
- r3 = _mm256_setzero_si256();
- r4 = _mm256_setzero_si256();
- r5 = _mm256_setzero_si256();
- r6 = _mm256_setzero_si256();
- r7 = _mm256_setzero_si256();
- for(unsigned i=0;i<4;i++) { ///
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i low1_low0 = temp&_0xf;
- __m256i high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- __m256i _temp = _mm256_load_si256( (__m256i*)(t32 + 4*32+ i*32) );
- __m256i _low1_low0 = _temp&_0xf;
- __m256i _high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , _temp ) , 4 );
-
- __m256i tab_0 = tab[i*16+0*2];
- __m256i tab_1 = tab[i*16+0*2+1];
- r0 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r4 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- tab_0 = tab[i*16+1*2];
- tab_1 = tab[i*16+1*2+1];
- r1 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r5 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- tab_0 = tab[i*16+2*2];
- tab_1 = tab[i*16+2*2+1];
- r2 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r6 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- tab_0 = tab[i*16+3*2];
- tab_1 = tab[i*16+3*2+1];
- r3 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r7 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- }
- _mm256_store_si256( (__m256i*)(r128_32+0*32+0) , r0 );
- _mm256_store_si256( (__m256i*)(r128_32+0*32+1*32) , r1 );
- _mm256_store_si256( (__m256i*)(r128_32+0*32+2*32) , r2 );
- _mm256_store_si256( (__m256i*)(r128_32+0*32+3*32) , r3 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+0*32) , r4 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+1*32) , r5 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+2*32) , r6 );
- _mm256_store_si256( (__m256i*)(r128_32+8*32+3*32) , r7 );
-
- r0 = _mm256_setzero_si256();
- r1 = _mm256_setzero_si256();
- r2 = _mm256_setzero_si256();
- r3 = _mm256_setzero_si256();
- r4 = _mm256_setzero_si256();
- r5 = _mm256_setzero_si256();
- r6 = _mm256_setzero_si256();
- r7 = _mm256_setzero_si256();
- for(unsigned i=0;i<4;i++) { ///
- __m256i temp = _mm256_load_si256( (__m256i*)(t32 + i*32) );
- __m256i low1_low0 = temp&_0xf;
- __m256i high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , temp ) , 4 );
-
- __m256i _temp = _mm256_load_si256( (__m256i*)(t32 + 4*32+ i*32) );
- __m256i _low1_low0 = _temp&_0xf;
- __m256i _high1_high0 = _mm256_srli_epi16( _mm256_andnot_si256( _0xf , _temp ) , 4 );
-
- __m256i tab_0 = tab[i*16+4*2];
- __m256i tab_1 = tab[i*16+4*2+1];
- r0 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r4 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- tab_0 = tab[i*16+5*2];
- tab_1 = tab[i*16+5*2+1];
- r1 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r5 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- tab_0 = tab[i*16+6*2];
- tab_1 = tab[i*16+6*2+1];
- r2 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r6 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- tab_0 = tab[i*16+7*2];
- tab_1 = tab[i*16+7*2+1];
- r3 ^= _mm256_shuffle_epi8( tab_0 , low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , high1_high0 );
- r7 ^= _mm256_shuffle_epi8( tab_0 , _low1_low0 ) ^ _mm256_shuffle_epi8( tab_1 , _high1_high0 );
- }
- _mm256_store_si256( (__m256i*)(r128_32+4*32+0) , r0 );
- _mm256_store_si256( (__m256i*)(r128_32+4*32+1*32) , r1 );
- _mm256_store_si256( (__m256i*)(r128_32+4*32+2*32) , r2 );
- _mm256_store_si256( (__m256i*)(r128_32+4*32+3*32) , r3 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+0*32) , r4 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+1*32) , r5 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+2*32) , r6 );
- _mm256_store_si256( (__m256i*)(r128_32+12*32+3*32) , r7 );
-
- transpose_8x8_b4_avx2( r128_32 , r128_32 );
- transpose_8x8_b4_avx2( r128_32+32*8 , r128_32+32*8 );
-}
-
-
-
-
-#endif
diff --git a/bitpolymul-test.cpp b/bitpolymul-test.cpp
deleted file mode 100644
index 413e3e6..0000000
--- a/bitpolymul-test.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-
-#include
-#include
-
-#include "benchmark.h"
-#include "byte_inline_func.h"
-
-#include "bitpolymul.h"
-
-#include "config_profile.h"
-
-#define TEST_RUN 100
-#define REF_RUN TEST_RUN
-
-#define TEST_CONSISTENCY
-
-//#define _HAVE_GF2X_
-
-#ifdef _HAVE_GF2X_
-#include "gf2x.h"
-void polymul_gf2x( uint64_t * c , const uint64_t * a , const uint64_t * b , unsigned terms )
-{
- gf2x_mul( c , a , terms , b , terms );
-}
-#endif
-
-
-#define STRINGIFY(x) #x
-#define TOSTRING(x) STRINGIFY(x)
-
-//#define bm_func1 bitpolymul_simple
-#define bm_func1 bitpolymul_2_64
-//#define bm_func1 bitpolymul_2
-//#define bm_func1 bitpolymul_128
-//#define bm_func1 bitpolymul
-#define n_fn1 "fn:" TOSTRING(bm_func1) "()"
-
-#ifdef _HAVE_GF2X_
-#define bm_func2 polymul_gf2x
-#else
-//#define bm_func2 bitpolymul_simple
-#define bm_func2 bitpolymul_2_128
-#endif
-#define n_fn2 "fn:" TOSTRING(bm_func2) "()"
-
-
-//#define _EXIT_WHILE_FAIL_
-
-#define LEN (1<<16)
-
-#define _DYNA_ALLOC_
-
-
-#ifdef _PROFILE_
-extern "C" {
-extern struct benchmark bm_ch;
-extern struct benchmark bm_tr;
-extern struct benchmark bm_tr2;
-
-extern struct benchmark bm_bc;
-extern struct benchmark bm_butterfly;
-extern struct benchmark bm_pointmul;
-extern struct benchmark bm_pointmul_tower;
-
-extern struct benchmark bm_ich;
-extern struct benchmark bm_ibc;
-extern struct benchmark bm_ibutterfly;
-
-//extern struct benchmark bm_bm;
-//extern struct benchmark bm_mul;
-}
-#endif
-
-#define LOG2(X) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((X)) - 1))
-
-int main( int argc , char ** argv )
-{
- //unsigned char seed[32] = {0};
-
- unsigned log2_len = LOG2(LEN);
- if( log2_len == LOG2(LEN-1) ) log2_len++;
- if( 2 == argc ) {
- log2_len = atoi( argv[1] );
- if( log2_len > 30 || 0 == log2_len ) {
- printf("Benchmark binary polynomial multiplications.\nUsage: exe [log2_len]\n\n");
- exit(-1);
- }
- }
- unsigned len = 1<= len ) {
- printf("poly1 :" ); u64_dump( poly1 , len ); puts("");
- printf("poly2 :" ); u64_dump( poly2 , len ); puts("");
- printf("poly3 :" ); u64_dump( poly3 , len*2 ); puts("");
- byte_xor( poly5 , poly3 , len*2 );
- if( ! byte_is_zero( poly5 , len*2 ) ) {
- printf("consistency fail: \n");
- printf("diff:"); u64_fdump(stdout,poly5,len*2); puts("");
- }
- }
-
- for(unsigned q=0;q= len ) {
- printf("poly1 :" ); u64_dump( poly1 , len ); puts("");
- printf("poly2 :" ); u64_dump( poly2 , len ); puts("");
- printf("poly3 :" ); u64_dump( poly3 , len*2 ); puts("");
- byte_xor( poly4 , poly3 , len*2 );
- if( ! byte_is_zero( poly4 , len*2 ) ) {
- printf("consistency fail: \n");
- printf("diff:"); u64_fdump(stdout,poly4,len*2); puts("");
- }
- }
-
- //for(int i=0;i<7;i++) bm_func2( o1 , poly1 , v1 );
- //exit(-1);
-
- unsigned fail_count = 0;
- unsigned chk = 0;
- for(unsigned i=0;i= REF_RUN) continue;
-BENCHMARK( bm2 , {
- bm_func2( poly4 , poly2 , poly1 , len );
-} );
-
- memcpy( poly5 , poly4 , sizeof(uint64_t)*len*2 );
- byte_xor( poly5 , poly3 , len*2 );
- chk |= ((unsigned*)(&poly5[0]))[0];
- if( ! byte_is_zero( poly5 , len*2 ) ) {
- fail_count ++;
-#ifdef TEST_CONSISTENCY
- printf("consistency fail: %d.\n", i);
- printf("res1:"); u64_fdump(stdout,poly3,len*2); puts("");
- printf("res2:"); u64_fdump(stdout,poly4,len*2); puts("");
- printf("diff:"); u64_fdump(stdout,poly5,len*2); puts("");
- printf("\n");
- exit(-1);
-#endif
- }
- }
-
- printf("fail count: %d.\n", fail_count );
- printf("check: %x\n", chk );
- char msg[256];
- bm_dump( msg , 256 , &bm1 );
- printf("benchmark (%s) :\n%s\n", n_fn1 , msg );
-
- bm_dump( msg , 256 , &bm2 );
- printf("benchmark (%s) :\n%s\n\n", n_fn2 , msg );
-
-#ifdef _PROFILE_
- bm_dump( msg , 256 , &bm_tr ); printf("benchmark (tr ) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_tr2 ); printf("benchmark (tr2) :\n%s\n", msg );
-// bm_dump( msg , 256 , &bm_mul ); printf("benchmark (mul) :\n%s\n", msg );
-// bm_dump( msg , 256 , &bm_bm ); printf("benchmark (bm ) :\n%s\n\n", msg );
-
- bm_dump( msg , 256 , &bm_ch ); printf("benchmark (ch ) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_bc ); printf("benchmark (bc) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_butterfly ); printf("benchmark (butterfly) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_pointmul ); printf("benchmark (pointmul) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_pointmul_tower ); printf("benchmark (pointmul_tower) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_ibutterfly ); printf("benchmark (ibutterfly) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_ibc ); printf("benchmark (ibc) :\n%s\n", msg );
- bm_dump( msg , 256 , &bm_ich ); printf("benchmark (ich ) :\n%s\n\n", msg );
-#endif
-
-#ifdef _DYNA_ALLOC_
- free( poly1 );
- free( poly2 );
- free( poly3 );
- free( poly4 );
-#endif
-
- return 0;
-}
diff --git a/bitpolymul.c b/bitpolymul.c
deleted file mode 100644
index d415f26..0000000
--- a/bitpolymul.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#include
-#include
-#include
-
-#include "bc.h"
-
-#include "butterfly_net.h"
-
-
-#include "config_profile.h"
-
-#define MAX_TERMS 65536
-
-#include "gfext_aesni.h"
-
-
-#ifdef _PROFILE_
-
-#include "benchmark.h"
-
-struct benchmark bm_ch;
-struct benchmark bm_bc;
-struct benchmark bm_butterfly;
-struct benchmark bm_pointmul;
-struct benchmark bm_pointmul_tower;
-
-struct benchmark bm_ich;
-struct benchmark bm_ibc;
-struct benchmark bm_ibutterfly;
-
-struct benchmark bm_tr;
-struct benchmark bm_tr2;
-
-#endif
-
-
-#define LOG2(X) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((X)) - 1))
-
-// for removing warning.
-void *aligned_alloc( size_t alignment, size_t size );
-
-
-void bitpolymul_simple( uint64_t * c , const uint64_t * a , const uint64_t * b , unsigned _n_64 )
-{
- if( 0 == _n_64 ) return;
- unsigned n_64 = 0;
- if( 1 == _n_64 ) n_64 = _n_64;
- else {
- unsigned log_2_n64 = LOG2(_n_64);
- unsigned log_2_n64_1 = LOG2(_n_64-1);
- if( log_2_n64 == log_2_n64_1 )log_2_n64 += 1;
- n_64 = 1< n_64 ) n_64 = 256;
-
- uint64_t * a_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64 );
- //uint64_t * a_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64*2 );
- if( NULL == a_bc ) { printf("alloc fail.\n"); exit(-1); }
- uint64_t * b_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64 );
- //uint64_t * b_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64*2 );
- if( NULL == b_bc ) { printf("alloc fail.\n"); exit(-1); }
-
-#ifdef _PROFILE_
-bm_start(&bm_bc);
-#endif
- memcpy( a_bc , a , sizeof(uint64_t)*_n_64 );
- for(unsigned i=_n_64;i (1<<26) ) { printf("un-supported length of polynomials."); exit(-1); }
- unsigned n_64 = 0;
- if( 1 == _n_64 ) n_64 = _n_64;
- else {
- unsigned log_2_n64 = LOG2(_n_64);
- unsigned log_2_n64_1 = LOG2(_n_64-1);
- if( log_2_n64 == log_2_n64_1 )log_2_n64 += 1;
- n_64 = 1< n_64 ) n_64 = 256;
-
- uint64_t * a_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64 );
- //uint64_t * a_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64*2 );
- if( NULL == a_bc ) { printf("alloc fail.\n"); exit(-1); }
- uint64_t * b_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64 );
- //uint64_t * b_bc = (uint64_t*)aligned_alloc( 32 , sizeof(uint64_t)*n_64*2 );
- if( NULL == b_bc ) { printf("alloc fail.\n"); exit(-1); }
-
-#ifdef _PROFILE_
-bm_start(&bm_bc);
-#endif
- memcpy( a_bc , a , sizeof(uint64_t)*_n_64 );
- for(unsigned i=_n_64;i
+ $)
+
diff --git a/bitpolymul/bc.cpp b/bitpolymul/bc.cpp
new file mode 100644
index 0000000..d6aaba8
--- /dev/null
+++ b/bitpolymul/bc.cpp
@@ -0,0 +1,305 @@
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+#include "bc.h"
+#include "bpmDefines.h"
+#include
+#include
+#include
+
+#define BC_CODE_GEN
+
+#define LOG2(X) ((u64) (8*sizeof (u64) - __builtin_clzll((X)) - 1))
+#define MAX(x,y) (((x)>(y))?(x):(y))
+#define MIN(x,y) (((x)<(y))?(x):(y))
+
+namespace bpm
+{
+
+
+ inline
+ void __xor_down_256(__m256i* poly, u64 dest_idx, u64 src_idx, u64 len)
+ {
+ for (u64 i = len; i > 0;) {
+ i--;
+ poly[dest_idx + i] = xor256(poly[dest_idx + i], poly[src_idx + i]);
+ }
+ }
+
+ //USED;
+ inline
+ void __xor_up_256(__m256i* poly, u64 dest_idx, u64 src_idx, u64 len)
+ {
+ for (u64 i = 0; i < len; i++) {
+ poly[dest_idx + i] = xor256(poly[dest_idx + i], poly[src_idx + i]);
+ }
+ }
+
+ inline
+ void __xor_down_256_2(__m256i* poly, u64 len, u64 l_st) {
+ __xor_down_256(poly, l_st, len, len);
+ }
+
+ inline
+ void xor_up_256(__m256i* poly, u64 st, u64 len, u64 diff)
+ {
+ __xor_up_256(poly, st, diff + st, len);
+ }
+
+ inline
+ void __xor_up_256_2(__m256i* poly, u64 len, u64 l_st) {
+ __xor_up_256(poly, l_st, len, len);
+ }
+
+
+
+ __m256i _mm256_alignr_255bit_zerohigh(__m256i zerohigh, __m256i low)
+ {
+ __m256i l_shr_15 = _mm256_srli_epi16(low, 15);
+ __m256i r_1 = _mm256_permute2x128_si256(l_shr_15, zerohigh, 0x21);
+ return _mm256_srli_si256(r_1, 14);
+ }
+
+
+ __m256i _mm256_alignr_254bit_zerohigh(__m256i zerohigh, __m256i low)
+ {
+ __m256i l_shr_14 = _mm256_srli_epi16(low, 14);
+ __m256i r_2 = _mm256_permute2x128_si256(l_shr_14, zerohigh, 0x21);
+ return _mm256_srli_si256(r_2, 14);
+ }
+
+
+ __m256i _mm256_alignr_252bit_zerohigh(__m256i zerohigh, __m256i low)
+ {
+ __m256i l_shr_12 = _mm256_srli_epi16(low, 12);
+ __m256i r_4 = _mm256_permute2x128_si256(l_shr_12, zerohigh, 0x21);
+ return _mm256_srli_si256(r_4, 14);
+ }
+
+
+ __m256i _mm256_alignr_255bit(__m256i high, __m256i low)
+ {
+ __m256i l_shr_15 = _mm256_srli_epi16(low, 15);
+ __m256i h_shr_15 = _mm256_srli_epi16(high, 15);
+ __m256i h_shl_1 = _mm256_slli_epi16(high, 1);
+ __m256i r = xor256(h_shl_1, _mm256_slli_si256(h_shr_15, 2));
+
+ __m256i r_1 = _mm256_permute2x128_si256(l_shr_15, h_shr_15, 0x21);
+ r = xor256(r, _mm256_srli_si256(r_1, 14));
+ return r;
+ }
+
+
+ __m256i _mm256_alignr_254bit(__m256i high, __m256i low)
+ {
+ __m256i l_shr_14 = _mm256_srli_epi16(low, 14);
+ __m256i h_shr_14 = _mm256_srli_epi16(high, 14);
+ __m256i h_shl_2 = _mm256_slli_epi16(high, 2);
+ __m256i r = xor256(h_shl_2, _mm256_slli_si256(h_shr_14, 2));
+
+ __m256i r_2 = _mm256_permute2x128_si256(l_shr_14, h_shr_14, 0x21);
+ r = xor256(r, _mm256_srli_si256(r_2, 14));
+ return r;
+ }
+
+
+ __m256i _mm256_alignr_252bit(__m256i high, __m256i low)
+ {
+ __m256i l_shr_12 = _mm256_srli_epi16(low, 12);
+ __m256i h_shr_12 = _mm256_srli_epi16(high, 12);
+ __m256i h_shl_4 = _mm256_slli_epi16(high, 4);
+ __m256i r = xor256(h_shl_4, _mm256_slli_si256(h_shr_12, 2));
+
+ __m256i r_4 = _mm256_permute2x128_si256(l_shr_12, h_shr_12, 0x21);
+ r = xor256(r, _mm256_srli_si256(r_4, 14));
+ return r;
+ }
+
+
+ __m256i _mm256_alignr_31byte(__m256i high, __m256i low)
+ {
+ __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21);
+ return _mm256_alignr_epi8(high, l0, 15);
+ }
+
+
+ __m256i _mm256_alignr_30byte(__m256i high, __m256i low)
+ {
+ __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21);
+ return _mm256_alignr_epi8(high, l0, 14);
+ }
+
+
+ __m256i _mm256_alignr_28byte(__m256i high, __m256i low)
+ {
+ __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21);
+ return _mm256_alignr_epi8(high, l0, 12);
+ }
+
+
+ __m256i _mm256_alignr_24byte(__m256i high, __m256i low)
+ {
+ __m256i l0 = _mm256_permute2x128_si256(low, high, 0x21);
+ return _mm256_alignr_epi8(high, l0, 8);
+ }
+
+
+ __m256i _mm256_alignr_16byte(__m256i high, __m256i low)
+ {
+ return _mm256_permute2x128_si256(low, high, 0x21);
+ }
+
+ //USED;
+
+ __m256i (*_sh_op[8]) (__m256i h, __m256i l) = {
+ _mm256_alignr_255bit, _mm256_alignr_254bit, _mm256_alignr_252bit, _mm256_alignr_31byte, _mm256_alignr_30byte, _mm256_alignr_28byte, _mm256_alignr_24byte, _mm256_alignr_16byte
+ };
+
+ //USED;
+
+ __m256i (*_sh_op_zerohigh[8]) (__m256i h, __m256i l) = {
+ _mm256_alignr_255bit_zerohigh , _mm256_alignr_254bit_zerohigh , _mm256_alignr_252bit_zerohigh , _mm256_alignr_31byte, _mm256_alignr_30byte, _mm256_alignr_28byte, _mm256_alignr_24byte, _mm256_alignr_16byte
+ };
+
+
+ //USED;
+ inline
+ void __sh_xor_down(__m256i* poly256, u64 unit, u64 _op, __m256i zero)
+ {
+ u64 unit_2 = unit >> 1;
+ poly256[unit_2] = xor256(poly256[unit_2], _sh_op_zerohigh[_op](zero, poly256[unit - 1]));
+ for (u64 i = 0; i < unit_2 - 1; i++) {
+ poly256[unit_2 - 1 - i] = xor256(poly256[unit_2 - 1 - i], _sh_op[_op](poly256[unit - 1 - i], poly256[unit - 2 - i]));
+ }
+ poly256[0] = xor256(poly256[0], _sh_op[_op](poly256[unit_2], zero));
+ }
+
+
+ //USED;
+
+ void varsub_x256(__m256i* poly256, u64 n_256)
+ {
+ if (1 >= n_256) return;
+ u64 log_n = __builtin_ctzll(n_256);
+ __m256i zero = _mm256_setzero_si256();
+
+ while (log_n > 8) {
+ u64 unit = 1ull << log_n;
+ u64 num = n_256 / unit;
+ u64 unit_2 = unit >> 1;
+ for (u64 j = 0; j < num; j++) __xor_down_256_2(poly256 + j * unit, unit_2, (1ull << (log_n - 9)));
+ log_n--;
+ }
+
+ for (u64 i = log_n; i > 0; i--) {
+ u64 unit = (1ull << i);
+ u64 num = n_256 / unit;
+ for (u64 j = 0; j < num; j++) __sh_xor_down(poly256 + j * unit, unit, i - 1, zero);
+ }
+
+ }
+
+
+ //USED;
+ inline
+ void __sh_xor_up(__m256i* poly256, u64 unit, u64 _op, __m256i zero)
+ {
+ u64 unit_2 = unit >> 1;
+ poly256[0] = xor256(poly256[0], _sh_op[_op](poly256[unit_2], zero));
+ for (u64 i = 0; i < unit_2 - 1; i++) {
+ poly256[i + 1] = xor256(poly256[i + 1], _sh_op[_op](poly256[unit_2 + i + 1], poly256[unit_2 + i]));
+ }
+ poly256[unit_2] = xor256(poly256[unit_2], _sh_op_zerohigh[_op](zero, poly256[unit - 1]));
+ }
+
+
+
+ //USED;
+
+ void i_varsub_x256(__m256i* poly256, u64 n_256)
+ {
+ if (1 >= n_256) return;
+ u64 log_n = __builtin_ctzll(n_256);
+ __m256i zero = _mm256_setzero_si256();
+
+ u64 _log_n = (log_n > 8) ? 8 : log_n;
+ for (u64 i = 1; i <= _log_n; i++) {
+ u64 unit = (1ull << i);
+ u64 num = n_256 / unit;
+ for (u64 j = 0; j < num; j++) __sh_xor_up(poly256 + j * unit, unit, i - 1, zero);
+ }
+
+ for (u64 i = 9; i <= log_n; i++) {
+ u64 unit = 1ull << i;
+ u64 num = n_256 / unit;
+ u64 unit_2 = unit >> 1;
+ for (u64 j = 0; j < num; j++) __xor_up_256_2(poly256 + j * unit, unit_2, (1ull << (i - 9)));
+ }
+ }
+
+ //USED;
+ void bc_to_lch_2_unit256(bc_sto_t* poly, u64 n_terms)
+ {
+ assert(0 == (n_terms & (n_terms - 1)));
+ assert(4 <= n_terms);
+
+ __m256i* poly256 = (__m256i*) poly;
+ u64 n_256 = n_terms >> 2;
+
+ varsub_x256(poly256, n_256);
+#ifdef BC_CODE_GEN
+ int logn = LOG2(n_256);
+ bc_to_lch_256_30_12(poly256, logn);
+ for (int i = 0; i < (1 << (MAX(0, logn - 19))); ++i) {
+ bc_to_lch_256_19_17(poly256 + i * (1ull << 19), MIN(19, logn));
+ }
+ for (int i = 0; i < (1 << (MAX(0, logn - 16))); ++i) {
+ bc_to_lch_256_16(poly256 + i * (1ull << 16), MIN(16, logn));
+ }
+#else
+ _bc_to_lch_256(poly256, n_256, 1);
+#endif
+ }
+
+
+ //USED;
+ void bc_to_mono_2_unit256(bc_sto_t* poly, u64 n_terms)
+ {
+ assert(0 == (n_terms & (n_terms - 1)));
+ assert(4 <= n_terms);
+
+ __m256i* poly256 = (__m256i*) poly;
+ u64 n_256 = n_terms >> 2;
+
+#ifdef BC_CODE_GEN
+ int logn = LOG2(n_256);
+ for (int i = 0; i < (1 << (MAX(0, logn - 16))); ++i) {
+ bc_to_mono_256_16(poly256 + i * (1ull << 16), MIN(16, logn));
+ }
+ for (int i = 0; i < (1 << (MAX(0, logn - 19))); ++i) {
+ bc_to_mono_256_19_17(poly256 + i * (1ull << 19), MIN(19, logn));
+ }
+ bc_to_mono_256_30_20(poly256, logn);
+#else
+ _bc_to_mono_256(poly256, n_256, 1);
+#endif
+ i_varsub_x256(poly256, n_256);
+ }
+
+}
diff --git a/bitpolymul.h b/bitpolymul/bc.h
similarity index 58%
rename from bitpolymul.h
rename to bitpolymul/bc.h
index 3ed943a..2c335b2 100644
--- a/bitpolymul.h
+++ b/bitpolymul/bc.h
@@ -1,3 +1,4 @@
+#pragma once
/*
Copyright (C) 2017 Ming-Shing Chen
@@ -17,30 +18,25 @@ You should have received a copy of the GNU Lesser General Public License
along with BitPolyMul. If not, see .
*/
-#ifndef _BITPOLYMUL_H_
-#define _BITPOLYMUL_H_
-
#include
+#include "bpmDefines.h"
-#define bitpolymul bitpolymul_2
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-void bitpolymul_simple( uint64_t * c , const uint64_t * a , const uint64_t * b , unsigned n_64 );
+namespace bpm {
-void bitpolymul_2_128( uint64_t * c , const uint64_t * a , const uint64_t * b , unsigned n_64 );
+ typedef uint64_t bc_sto_t;
+ void bc_to_lch_256_30_12(__m256i* poly, int logn);
+ void bc_to_lch_256_19_17(__m256i* poly, int logn);
+ void bc_to_lch_256_16(__m256i* poly, int logn);
+ void bc_to_mono_256_16(__m256i* poly, int logn);
+ void bc_to_mono_256_19_17(__m256i* poly, int logn);
+ void bc_to_mono_256_30_20(__m256i* poly, int logn);
-void bitpolymul_2_64( uint64_t * c , const uint64_t * a , const uint64_t * b , unsigned n_64 );
+ void bc_to_lch_2_unit256(bc_sto_t* poly, u64 n_terms);
+ void bc_to_mono_2_unit256(bc_sto_t* poly, u64 n_terms);
-#ifdef __cplusplus
}
-#endif
-#endif
diff --git a/bitpolymul/bc_to_gen_code.h b/bitpolymul/bc_to_gen_code.h
new file mode 100644
index 0000000..9af7b39
--- /dev/null
+++ b/bitpolymul/bc_to_gen_code.h
@@ -0,0 +1,48 @@
+#pragma once
+
+
+#include
+#define x(v1, v2) _mm256_xor_si256(v1,v2)
+#define m __m256i
+
+#define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
+#define BOOST_PP_CAT_I(a, b) a ## b
+
+#if _MSC_VER
+# define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_CAT(BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),)
+#else
+# define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
+#endif
+#define BOOST_PP_VARIADIC_SIZE_I(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size
+
+namespace bpm
+{
+
+ inline void xorEq_1(m* v1, m v2) { *v1 = x(*v1, v2); }
+ inline void xorEq_2(m* v1, m v2, m v3) { *v1 = x(x(*v1, v2), v3); }
+ inline void xorEq_3(m* v1, m v2, m v3, m v4) { *v1 = x(x(x(*v1, v2), v3), v4); }
+ inline void xorEq_4(m* v1, m v2, m v3, m v4, m v5) { *v1 = x(x(x(x(*v1, v2), v3), v4), v5); }
+ inline void xorEq_5(m* v1, m v2, m v3, m v4, m v5, m v6) { *v1 = x(x(x(x(x(*v1, v2), v3), v4), v5), v6); }
+ inline void xorEq_6(m* v1, m v2, m v3, m v4, m v5, m v6, m v7) { *v1 = x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7); }
+ inline void xorEq_7(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8) { *v1 = x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8); }
+ inline void xorEq_8(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9) { *v1 = x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9); }
+ inline void xorEq_9(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10) { *v1 = x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10); }
+ inline void xorEq_10(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11) { *v1 = x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11); }
+ inline void xorEq_11(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12) { *v1 = x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12); }
+ inline void xorEq_12(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13); }
+ inline void xorEq_13(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14); }
+ inline void xorEq_14(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15); }
+ inline void xorEq_15(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16); }
+ inline void xorEq_16(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17); }
+ inline void xorEq_17(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18); }
+ inline void xorEq_18(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19); }
+ inline void xorEq_19(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20); }
+ inline void xorEq_20(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20, m v21) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20), v21); }
+ inline void xorEq_21(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20, m v21, m v22) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20), v21), v22); }
+ inline void xorEq_22(m* v1, m v2, m v3, m v4, m v5, m v6, m v7, m v8, m v9, m v10, m v11, m v12, m v13, m v14, m v15, m v16, m v17, m v18, m v19, m v20, m v21, m v22, m v23) { *v1 = x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(x(*v1, v2), v3), v4), v5), v6), v7), v8), v9), v10), v11), v12), v13), v14), v15), v16), v17), v18), v19), v20), v21), v22), v23); }
+}
+
+#define xorEq(v1, ...) BOOST_PP_CAT(xorEq_, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))(&v1, __VA_ARGS__)
+
+#undef m
+#undef x
diff --git a/bitpolymul/bc_to_lch_gen_code.cpp b/bitpolymul/bc_to_lch_gen_code.cpp
new file mode 100644
index 0000000..e4f26bc
--- /dev/null
+++ b/bitpolymul/bc_to_lch_gen_code.cpp
@@ -0,0 +1,481 @@
+/*
+Copyright (C) 2018 Wen-Ding Li
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+#include "bc_to_gen_code.h"
+namespace bpm {
+void bc_to_lch_256_30_12(__m256i* poly, int logn){
+for(int offset=(1<<30);offset<(1<=offset+(1<<30)-1006632960;--i)xorEq(poly[i],poly[i+805306368]);
+for(int i=offset+(1<<30)-1-1006632960;i>=offset+(1<<30)-1056964608;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960]);
+for(int i=offset+(1<<30)-1-1056964608;i>=offset+(1<<30)-1069547520;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608]);
+for(int i=offset+(1<<30)-1-1069547520;i>=offset+(1<<30)-1072693248;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520]);
+for(int i=offset+(1<<30)-1-1072693248;i>=offset+(1<<30)-1073479680;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248]);
+for(int i=offset+(1<<30)-1-1073479680;i>=offset+(1<<30)-1073676288;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680]);
+for(int i=offset+(1<<30)-1-1073676288;i>=offset+(1<<30)-1073725440;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288]);
+for(int i=offset+(1<<30)-1-1073725440;i>=offset+(1<<30)-1073737728;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440]);
+for(int i=offset+(1<<30)-1-1073737728;i>=offset+(1<<30)-1073740800;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728]);
+for(int i=offset+(1<<30)-1-1073740800;i>=offset+(1<<30)-1073741568;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800]);
+for(int i=offset+(1<<30)-1-1073741568;i>=offset+(1<<30)-1073741760;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568]);
+for(int i=offset+(1<<30)-1-1073741760;i>=offset+(1<<30)-1073741808;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760]);
+for(int i=offset+(1<<30)-1-1073741808;i>=offset+(1<<30)-1073741820;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808]);
+for(int i=offset+(1<<30)-1-1073741820;i>=offset+(1<<30)-1073741823;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820]);
+for(int i=offset+(1<<30)-1-1073741823;i>=offset+(1<<30)-1073741824;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-0;i>=offset-805306368;--i)xorEq(poly[i],poly[i+805306368],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-805306368;i>=offset-1006632960;--i)xorEq(poly[i],poly[i+1006632960],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1006632960;i>=offset-1056964608;--i)xorEq(poly[i],poly[i+1056964608],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1056964608;i>=offset-1069547520;--i)xorEq(poly[i],poly[i+1069547520],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1069547520;i>=offset-1072693248;--i)xorEq(poly[i],poly[i+1072693248],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1072693248;i>=offset-1073479680;--i)xorEq(poly[i],poly[i+1073479680],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073479680;i>=offset-1073676288;--i)xorEq(poly[i],poly[i+1073676288],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073676288;i>=offset-1073725440;--i)xorEq(poly[i],poly[i+1073725440],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073725440;i>=offset-1073737728;--i)xorEq(poly[i],poly[i+1073737728],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073737728;i>=offset-1073740800;--i)xorEq(poly[i],poly[i+1073740800],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073740800;i>=offset-1073741568;--i)xorEq(poly[i],poly[i+1073741568],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073741568;i>=offset-1073741760;--i)xorEq(poly[i],poly[i+1073741760],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073741760;i>=offset-1073741808;--i)xorEq(poly[i],poly[i+1073741808],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073741808;i>=offset-1073741820;--i)xorEq(poly[i],poly[i+1073741820],poly[i+1073741823]);
+for(int i=offset-1-1073741820;i>=offset-1073741823;--i)xorEq(poly[i],poly[i+1073741823]);
+
+}
+for(int offset=(1<<29);offset<(1<=offset+(1<<29)-503316480;--i)xorEq(poly[i],poly[i+268435456]);
+for(int i=offset+(1<<29)-1-503316480;i>=offset+(1<<29)-520093696;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480]);
+for(int i=offset+(1<<29)-1-520093696;i>=offset+(1<<29)-534773760;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696]);
+for(int i=offset+(1<<29)-1-534773760;i>=offset+(1<<29)-535822336;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760]);
+for(int i=offset+(1<<29)-1-535822336;i>=offset+(1<<29)-536739840;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336]);
+for(int i=offset+(1<<29)-1-536739840;i>=offset+(1<<29)-536805376;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840]);
+for(int i=offset+(1<<29)-1-536805376;i>=offset+(1<<29)-536862720;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376]);
+for(int i=offset+(1<<29)-1-536862720;i>=offset+(1<<29)-536866816;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720]);
+for(int i=offset+(1<<29)-1-536866816;i>=offset+(1<<29)-536870400;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816]);
+for(int i=offset+(1<<29)-1-536870400;i>=offset+(1<<29)-536870656;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400]);
+for(int i=offset+(1<<29)-1-536870656;i>=offset+(1<<29)-536870880;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656]);
+for(int i=offset+(1<<29)-1-536870880;i>=offset+(1<<29)-536870896;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880]);
+for(int i=offset+(1<<29)-1-536870896;i>=offset+(1<<29)-536870910;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896]);
+for(int i=offset+(1<<29)-1-536870910;i>=offset+(1<<29)-536870911;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910]);
+for(int i=offset+(1<<29)-1-536870911;i>=offset+(1<<29)-536870912;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-0;i>=offset-268435456;--i)xorEq(poly[i],poly[i+268435456],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-268435456;i>=offset-503316480;--i)xorEq(poly[i],poly[i+503316480],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-503316480;i>=offset-520093696;--i)xorEq(poly[i],poly[i+520093696],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-520093696;i>=offset-534773760;--i)xorEq(poly[i],poly[i+534773760],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-534773760;i>=offset-535822336;--i)xorEq(poly[i],poly[i+535822336],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-535822336;i>=offset-536739840;--i)xorEq(poly[i],poly[i+536739840],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536739840;i>=offset-536805376;--i)xorEq(poly[i],poly[i+536805376],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536805376;i>=offset-536862720;--i)xorEq(poly[i],poly[i+536862720],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536862720;i>=offset-536866816;--i)xorEq(poly[i],poly[i+536866816],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536866816;i>=offset-536870400;--i)xorEq(poly[i],poly[i+536870400],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536870400;i>=offset-536870656;--i)xorEq(poly[i],poly[i+536870656],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536870656;i>=offset-536870880;--i)xorEq(poly[i],poly[i+536870880],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536870880;i>=offset-536870896;--i)xorEq(poly[i],poly[i+536870896],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536870896;i>=offset-536870910;--i)xorEq(poly[i],poly[i+536870910],poly[i+536870911]);
+for(int i=offset-1-536870910;i>=offset-536870911;--i)xorEq(poly[i],poly[i+536870911]);
+
+}
+for(int offset=(1<<28);offset<(1<=offset+(1<<28)-267386880;--i)xorEq(poly[i],poly[i+251658240]);
+for(int i=offset+(1<<28)-1-267386880;i>=offset+(1<<28)-268369920;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880]);
+for(int i=offset+(1<<28)-1-268369920;i>=offset+(1<<28)-268431360;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920]);
+for(int i=offset+(1<<28)-1-268431360;i>=offset+(1<<28)-268435200;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360]);
+for(int i=offset+(1<<28)-1-268435200;i>=offset+(1<<28)-268435440;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200]);
+for(int i=offset+(1<<28)-1-268435440;i>=offset+(1<<28)-268435455;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440]);
+for(int i=offset+(1<<28)-1-268435455;i>=offset+(1<<28)-268435456;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-0;i>=offset-251658240;--i)xorEq(poly[i],poly[i+251658240],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-251658240;i>=offset-267386880;--i)xorEq(poly[i],poly[i+267386880],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-267386880;i>=offset-268369920;--i)xorEq(poly[i],poly[i+268369920],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-268369920;i>=offset-268431360;--i)xorEq(poly[i],poly[i+268431360],poly[i+268435200],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-268431360;i>=offset-268435200;--i)xorEq(poly[i],poly[i+268435200],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-268435200;i>=offset-268435440;--i)xorEq(poly[i],poly[i+268435440],poly[i+268435455]);
+for(int i=offset-1-268435440;i>=offset-268435455;--i)xorEq(poly[i],poly[i+268435455]);
+
+}
+for(int offset=(1<<27);offset<(1<=offset+(1<<27)-100663296;--i)xorEq(poly[i],poly[i+67108864]);
+for(int i=offset+(1<<27)-1-100663296;i>=offset+(1<<27)-117440512;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296]);
+for(int i=offset+(1<<27)-1-117440512;i>=offset+(1<<27)-133693440;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512]);
+for(int i=offset+(1<<27)-1-133693440;i>=offset+(1<<27)-133955584;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440]);
+for(int i=offset+(1<<27)-1-133955584;i>=offset+(1<<27)-134086656;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584]);
+for(int i=offset+(1<<27)-1-134086656;i>=offset+(1<<27)-134152192;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656]);
+for(int i=offset+(1<<27)-1-134152192;i>=offset+(1<<27)-134215680;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192]);
+for(int i=offset+(1<<27)-1-134215680;i>=offset+(1<<27)-134216704;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680]);
+for(int i=offset+(1<<27)-1-134216704;i>=offset+(1<<27)-134217216;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704]);
+for(int i=offset+(1<<27)-1-134217216;i>=offset+(1<<27)-134217472;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216]);
+for(int i=offset+(1<<27)-1-134217472;i>=offset+(1<<27)-134217720;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472]);
+for(int i=offset+(1<<27)-1-134217720;i>=offset+(1<<27)-134217724;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720]);
+for(int i=offset+(1<<27)-1-134217724;i>=offset+(1<<27)-134217726;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724]);
+for(int i=offset+(1<<27)-1-134217726;i>=offset+(1<<27)-134217727;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726]);
+for(int i=offset+(1<<27)-1-134217727;i>=offset+(1<<27)-134217728;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-0;i>=offset-67108864;--i)xorEq(poly[i],poly[i+67108864],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-67108864;i>=offset-100663296;--i)xorEq(poly[i],poly[i+100663296],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-100663296;i>=offset-117440512;--i)xorEq(poly[i],poly[i+117440512],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-117440512;i>=offset-133693440;--i)xorEq(poly[i],poly[i+133693440],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-133693440;i>=offset-133955584;--i)xorEq(poly[i],poly[i+133955584],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-133955584;i>=offset-134086656;--i)xorEq(poly[i],poly[i+134086656],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134086656;i>=offset-134152192;--i)xorEq(poly[i],poly[i+134152192],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134152192;i>=offset-134215680;--i)xorEq(poly[i],poly[i+134215680],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134215680;i>=offset-134216704;--i)xorEq(poly[i],poly[i+134216704],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134216704;i>=offset-134217216;--i)xorEq(poly[i],poly[i+134217216],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134217216;i>=offset-134217472;--i)xorEq(poly[i],poly[i+134217472],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134217472;i>=offset-134217720;--i)xorEq(poly[i],poly[i+134217720],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134217720;i>=offset-134217724;--i)xorEq(poly[i],poly[i+134217724],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134217724;i>=offset-134217726;--i)xorEq(poly[i],poly[i+134217726],poly[i+134217727]);
+for(int i=offset-1-134217726;i>=offset-134217727;--i)xorEq(poly[i],poly[i+134217727]);
+
+}
+for(int offset=(1<<26);offset<(1<=offset+(1<<26)-66846720;--i)xorEq(poly[i],poly[i+50331648]);
+for(int i=offset+(1<<26)-1-66846720;i>=offset+(1<<26)-67043328;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720]);
+for(int i=offset+(1<<26)-1-67043328;i>=offset+(1<<26)-67107840;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328]);
+for(int i=offset+(1<<26)-1-67107840;i>=offset+(1<<26)-67108608;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840]);
+for(int i=offset+(1<<26)-1-67108608;i>=offset+(1<<26)-67108860;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608]);
+for(int i=offset+(1<<26)-1-67108860;i>=offset+(1<<26)-67108863;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860]);
+for(int i=offset+(1<<26)-1-67108863;i>=offset+(1<<26)-67108864;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-0;i>=offset-50331648;--i)xorEq(poly[i],poly[i+50331648],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-50331648;i>=offset-66846720;--i)xorEq(poly[i],poly[i+66846720],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-66846720;i>=offset-67043328;--i)xorEq(poly[i],poly[i+67043328],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-67043328;i>=offset-67107840;--i)xorEq(poly[i],poly[i+67107840],poly[i+67108608],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-67107840;i>=offset-67108608;--i)xorEq(poly[i],poly[i+67108608],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-67108608;i>=offset-67108860;--i)xorEq(poly[i],poly[i+67108860],poly[i+67108863]);
+for(int i=offset-1-67108860;i>=offset-67108863;--i)xorEq(poly[i],poly[i+67108863]);
+
+}
+for(int offset=(1<<25);offset<(1<=offset+(1<<25)-33423360;--i)xorEq(poly[i],poly[i+16777216]);
+for(int i=offset+(1<<25)-1-33423360;i>=offset+(1<<25)-33488896;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360]);
+for(int i=offset+(1<<25)-1-33488896;i>=offset+(1<<25)-33553920;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896]);
+for(int i=offset+(1<<25)-1-33553920;i>=offset+(1<<25)-33554176;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920]);
+for(int i=offset+(1<<25)-1-33554176;i>=offset+(1<<25)-33554430;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176]);
+for(int i=offset+(1<<25)-1-33554430;i>=offset+(1<<25)-33554431;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430]);
+for(int i=offset+(1<<25)-1-33554431;i>=offset+(1<<25)-33554432;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-0;i>=offset-16777216;--i)xorEq(poly[i],poly[i+16777216],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-16777216;i>=offset-33423360;--i)xorEq(poly[i],poly[i+33423360],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-33423360;i>=offset-33488896;--i)xorEq(poly[i],poly[i+33488896],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-33488896;i>=offset-33553920;--i)xorEq(poly[i],poly[i+33553920],poly[i+33554176],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-33553920;i>=offset-33554176;--i)xorEq(poly[i],poly[i+33554176],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-33554176;i>=offset-33554430;--i)xorEq(poly[i],poly[i+33554430],poly[i+33554431]);
+for(int i=offset-1-33554430;i>=offset-33554431;--i)xorEq(poly[i],poly[i+33554431]);
+
+}
+for(int offset=(1<<24);offset<(1<=offset+(1<<24)-16776960;--i)xorEq(poly[i],poly[i+16711680]);
+for(int i=offset+(1<<24)-1-16776960;i>=offset+(1<<24)-16777215;--i)xorEq(poly[i],poly[i+16711680],poly[i+16776960]);
+for(int i=offset+(1<<24)-1-16777215;i>=offset+(1<<24)-16777216;--i)xorEq(poly[i],poly[i+16711680],poly[i+16776960],poly[i+16777215]);
+for(int i=offset-1-0;i>=offset-16711680;--i)xorEq(poly[i],poly[i+16711680],poly[i+16776960],poly[i+16777215]);
+for(int i=offset-1-16711680;i>=offset-16776960;--i)xorEq(poly[i],poly[i+16776960],poly[i+16777215]);
+for(int i=offset-1-16776960;i>=offset-16777215;--i)xorEq(poly[i],poly[i+16777215]);
+
+}
+for(int offset=(1<<23);offset<(1<=offset+(1<<23)-6291456;--i)xorEq(poly[i],poly[i+4194304]);
+for(int i=offset+(1<<23)-1-6291456;i>=offset+(1<<23)-7340032;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456]);
+for(int i=offset+(1<<23)-1-7340032;i>=offset+(1<<23)-7864320;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032]);
+for(int i=offset+(1<<23)-1-7864320;i>=offset+(1<<23)-8126464;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320]);
+for(int i=offset+(1<<23)-1-8126464;i>=offset+(1<<23)-8257536;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464]);
+for(int i=offset+(1<<23)-1-8257536;i>=offset+(1<<23)-8323072;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536]);
+for(int i=offset+(1<<23)-1-8323072;i>=offset+(1<<23)-8388480;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072]);
+for(int i=offset+(1<<23)-1-8388480;i>=offset+(1<<23)-8388544;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480]);
+for(int i=offset+(1<<23)-1-8388544;i>=offset+(1<<23)-8388576;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544]);
+for(int i=offset+(1<<23)-1-8388576;i>=offset+(1<<23)-8388592;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576]);
+for(int i=offset+(1<<23)-1-8388592;i>=offset+(1<<23)-8388600;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592]);
+for(int i=offset+(1<<23)-1-8388600;i>=offset+(1<<23)-8388604;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600]);
+for(int i=offset+(1<<23)-1-8388604;i>=offset+(1<<23)-8388606;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604]);
+for(int i=offset+(1<<23)-1-8388606;i>=offset+(1<<23)-8388607;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606]);
+for(int i=offset+(1<<23)-1-8388607;i>=offset+(1<<23)-8388608;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-0;i>=offset-4194304;--i)xorEq(poly[i],poly[i+4194304],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-4194304;i>=offset-6291456;--i)xorEq(poly[i],poly[i+6291456],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-6291456;i>=offset-7340032;--i)xorEq(poly[i],poly[i+7340032],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-7340032;i>=offset-7864320;--i)xorEq(poly[i],poly[i+7864320],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-7864320;i>=offset-8126464;--i)xorEq(poly[i],poly[i+8126464],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8126464;i>=offset-8257536;--i)xorEq(poly[i],poly[i+8257536],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8257536;i>=offset-8323072;--i)xorEq(poly[i],poly[i+8323072],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8323072;i>=offset-8388480;--i)xorEq(poly[i],poly[i+8388480],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388480;i>=offset-8388544;--i)xorEq(poly[i],poly[i+8388544],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388544;i>=offset-8388576;--i)xorEq(poly[i],poly[i+8388576],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388576;i>=offset-8388592;--i)xorEq(poly[i],poly[i+8388592],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388592;i>=offset-8388600;--i)xorEq(poly[i],poly[i+8388600],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388600;i>=offset-8388604;--i)xorEq(poly[i],poly[i+8388604],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388604;i>=offset-8388606;--i)xorEq(poly[i],poly[i+8388606],poly[i+8388607]);
+for(int i=offset-1-8388606;i>=offset-8388607;--i)xorEq(poly[i],poly[i+8388607]);
+
+}
+for(int offset=(1<<22);offset<(1<=offset+(1<<22)-3932160;--i)xorEq(poly[i],poly[i+3145728]);
+for(int i=offset+(1<<22)-1-3932160;i>=offset+(1<<22)-4128768;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160]);
+for(int i=offset+(1<<22)-1-4128768;i>=offset+(1<<22)-4194240;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768]);
+for(int i=offset+(1<<22)-1-4194240;i>=offset+(1<<22)-4194288;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240]);
+for(int i=offset+(1<<22)-1-4194288;i>=offset+(1<<22)-4194300;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288]);
+for(int i=offset+(1<<22)-1-4194300;i>=offset+(1<<22)-4194303;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300]);
+for(int i=offset+(1<<22)-1-4194303;i>=offset+(1<<22)-4194304;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-0;i>=offset-3145728;--i)xorEq(poly[i],poly[i+3145728],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-3145728;i>=offset-3932160;--i)xorEq(poly[i],poly[i+3932160],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-3932160;i>=offset-4128768;--i)xorEq(poly[i],poly[i+4128768],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-4128768;i>=offset-4194240;--i)xorEq(poly[i],poly[i+4194240],poly[i+4194288],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-4194240;i>=offset-4194288;--i)xorEq(poly[i],poly[i+4194288],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-4194288;i>=offset-4194300;--i)xorEq(poly[i],poly[i+4194300],poly[i+4194303]);
+for(int i=offset-1-4194300;i>=offset-4194303;--i)xorEq(poly[i],poly[i+4194303]);
+
+}
+for(int offset=(1<<21);offset<(1<=offset+(1<<21)-1966080;--i)xorEq(poly[i],poly[i+1048576]);
+for(int i=offset+(1<<21)-1-1966080;i>=offset+(1<<21)-2031616;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080]);
+for(int i=offset+(1<<21)-1-2031616;i>=offset+(1<<21)-2097120;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616]);
+for(int i=offset+(1<<21)-1-2097120;i>=offset+(1<<21)-2097136;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120]);
+for(int i=offset+(1<<21)-1-2097136;i>=offset+(1<<21)-2097150;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136]);
+for(int i=offset+(1<<21)-1-2097150;i>=offset+(1<<21)-2097151;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150]);
+for(int i=offset+(1<<21)-1-2097151;i>=offset+(1<<21)-2097152;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-0;i>=offset-1048576;--i)xorEq(poly[i],poly[i+1048576],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-1048576;i>=offset-1966080;--i)xorEq(poly[i],poly[i+1966080],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-1966080;i>=offset-2031616;--i)xorEq(poly[i],poly[i+2031616],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-2031616;i>=offset-2097120;--i)xorEq(poly[i],poly[i+2097120],poly[i+2097136],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-2097120;i>=offset-2097136;--i)xorEq(poly[i],poly[i+2097136],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-2097136;i>=offset-2097150;--i)xorEq(poly[i],poly[i+2097150],poly[i+2097151]);
+for(int i=offset-1-2097150;i>=offset-2097151;--i)xorEq(poly[i],poly[i+2097151]);
+
+}
+for(int offset=(1<<20);offset<(1<=offset+(1<<20)-1048560;--i)xorEq(poly[i],poly[i+983040]);
+for(int i=offset+(1<<20)-1-1048560;i>=offset+(1<<20)-1048575;--i)xorEq(poly[i],poly[i+983040],poly[i+1048560]);
+for(int i=offset+(1<<20)-1-1048575;i>=offset+(1<<20)-1048576;--i)xorEq(poly[i],poly[i+983040],poly[i+1048560],poly[i+1048575]);
+for(int i=offset-1-0;i>=offset-983040;--i)xorEq(poly[i],poly[i+983040],poly[i+1048560],poly[i+1048575]);
+for(int i=offset-1-983040;i>=offset-1048560;--i)xorEq(poly[i],poly[i+1048560],poly[i+1048575]);
+for(int i=offset-1-1048560;i>=offset-1048575;--i)xorEq(poly[i],poly[i+1048575]);
+
+}
+for(int offset=(1<<19);offset<(1<=offset+(1<<19)-393216;--i)xorEq(poly[i],poly[i+262144]);
+for(int i=offset+(1<<19)-1-393216;i>=offset+(1<<19)-458752;--i)xorEq(poly[i],poly[i+262144],poly[i+393216]);
+for(int i=offset+(1<<19)-1-458752;i>=offset+(1<<19)-524280;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752]);
+for(int i=offset+(1<<19)-1-524280;i>=offset+(1<<19)-524284;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280]);
+for(int i=offset+(1<<19)-1-524284;i>=offset+(1<<19)-524286;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284]);
+for(int i=offset+(1<<19)-1-524286;i>=offset+(1<<19)-524287;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286]);
+for(int i=offset+(1<<19)-1-524287;i>=offset+(1<<19)-524288;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-0;i>=offset-262144;--i)xorEq(poly[i],poly[i+262144],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-262144;i>=offset-393216;--i)xorEq(poly[i],poly[i+393216],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-393216;i>=offset-458752;--i)xorEq(poly[i],poly[i+458752],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-458752;i>=offset-524280;--i)xorEq(poly[i],poly[i+524280],poly[i+524284],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-524280;i>=offset-524284;--i)xorEq(poly[i],poly[i+524284],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-524284;i>=offset-524286;--i)xorEq(poly[i],poly[i+524286],poly[i+524287]);
+for(int i=offset-1-524286;i>=offset-524287;--i)xorEq(poly[i],poly[i+524287]);
+
+}
+}
+
+void bc_to_lch_256_19_17(__m256i* poly, int logn){
+for(int offset=(1<<18);offset<(1<=offset+(1<<18)-262140;--i)xorEq(poly[i],poly[i+196608]);
+for(int i=offset+(1<<18)-1-262140;i>=offset+(1<<18)-262143;--i)xorEq(poly[i],poly[i+196608],poly[i+262140]);
+for(int i=offset+(1<<18)-1-262143;i>=offset+(1<<18)-262144;--i)xorEq(poly[i],poly[i+196608],poly[i+262140],poly[i+262143]);
+for(int i=offset-1-0;i>=offset-196608;--i)xorEq(poly[i],poly[i+196608],poly[i+262140],poly[i+262143]);
+for(int i=offset-1-196608;i>=offset-262140;--i)xorEq(poly[i],poly[i+262140],poly[i+262143]);
+for(int i=offset-1-262140;i>=offset-262143;--i)xorEq(poly[i],poly[i+262143]);
+
+}
+for(int offset=(1<<17);offset<(1<=offset+(1<<17)-131070;--i)xorEq(poly[i],poly[i+65536]);
+for(int i=offset+(1<<17)-1-131070;i>=offset+(1<<17)-131071;--i)xorEq(poly[i],poly[i+65536],poly[i+131070]);
+for(int i=offset+(1<<17)-1-131071;i>=offset+(1<<17)-131072;--i)xorEq(poly[i],poly[i+65536],poly[i+131070],poly[i+131071]);
+for(int i=offset-1-0;i>=offset-65536;--i)xorEq(poly[i],poly[i+65536],poly[i+131070],poly[i+131071]);
+for(int i=offset-1-65536;i>=offset-131070;--i)xorEq(poly[i],poly[i+131070],poly[i+131071]);
+for(int i=offset-1-131070;i>=offset-131071;--i)xorEq(poly[i],poly[i+131071]);
+
+}
+for(int offset=(1<<16);offset<(1<=offset+(1<<16)-65536;--i)xorEq(poly[i],poly[i+65535]);
+for(int i=offset-1-0;i>=offset-65535;--i)xorEq(poly[i],poly[i+65535]);
+
+}
+}
+
+void bc_to_lch_256_16(__m256i* poly, int logn){
+for(int offset=(1<<15);offset<(1<=offset+(1<<15)-24576;--i)xorEq(poly[i],poly[i+16384]);
+for(int i=offset+(1<<15)-1-24576;i>=offset+(1<<15)-28672;--i)xorEq(poly[i],poly[i+16384],poly[i+24576]);
+for(int i=offset+(1<<15)-1-28672;i>=offset+(1<<15)-30720;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672]);
+for(int i=offset+(1<<15)-1-30720;i>=offset+(1<<15)-31744;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720]);
+for(int i=offset+(1<<15)-1-31744;i>=offset+(1<<15)-32256;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744]);
+for(int i=offset+(1<<15)-1-32256;i>=offset+(1<<15)-32512;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256]);
+for(int i=offset+(1<<15)-1-32512;i>=offset+(1<<15)-32640;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512]);
+for(int i=offset+(1<<15)-1-32640;i>=offset+(1<<15)-32704;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640]);
+for(int i=offset+(1<<15)-1-32704;i>=offset+(1<<15)-32736;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704]);
+for(int i=offset+(1<<15)-1-32736;i>=offset+(1<<15)-32752;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736]);
+for(int i=offset+(1<<15)-1-32752;i>=offset+(1<<15)-32760;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752]);
+for(int i=offset+(1<<15)-1-32760;i>=offset+(1<<15)-32764;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760]);
+for(int i=offset+(1<<15)-1-32764;i>=offset+(1<<15)-32766;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764]);
+for(int i=offset+(1<<15)-1-32766;i>=offset+(1<<15)-32767;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766]);
+for(int i=offset+(1<<15)-1-32767;i>=offset+(1<<15)-32768;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-0;i>=offset-16384;--i)xorEq(poly[i],poly[i+16384],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-16384;i>=offset-24576;--i)xorEq(poly[i],poly[i+24576],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-24576;i>=offset-28672;--i)xorEq(poly[i],poly[i+28672],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-28672;i>=offset-30720;--i)xorEq(poly[i],poly[i+30720],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-30720;i>=offset-31744;--i)xorEq(poly[i],poly[i+31744],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-31744;i>=offset-32256;--i)xorEq(poly[i],poly[i+32256],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32256;i>=offset-32512;--i)xorEq(poly[i],poly[i+32512],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32512;i>=offset-32640;--i)xorEq(poly[i],poly[i+32640],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32640;i>=offset-32704;--i)xorEq(poly[i],poly[i+32704],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32704;i>=offset-32736;--i)xorEq(poly[i],poly[i+32736],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32736;i>=offset-32752;--i)xorEq(poly[i],poly[i+32752],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32752;i>=offset-32760;--i)xorEq(poly[i],poly[i+32760],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32760;i>=offset-32764;--i)xorEq(poly[i],poly[i+32764],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32764;i>=offset-32766;--i)xorEq(poly[i],poly[i+32766],poly[i+32767]);
+for(int i=offset-1-32766;i>=offset-32767;--i)xorEq(poly[i],poly[i+32767]);
+
+}
+for(int offset=(1<<14);offset<(1<=offset+(1<<14)-15360;--i)xorEq(poly[i],poly[i+12288]);
+for(int i=offset+(1<<14)-1-15360;i>=offset+(1<<14)-16128;--i)xorEq(poly[i],poly[i+12288],poly[i+15360]);
+for(int i=offset+(1<<14)-1-16128;i>=offset+(1<<14)-16320;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128]);
+for(int i=offset+(1<<14)-1-16320;i>=offset+(1<<14)-16368;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320]);
+for(int i=offset+(1<<14)-1-16368;i>=offset+(1<<14)-16380;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368]);
+for(int i=offset+(1<<14)-1-16380;i>=offset+(1<<14)-16383;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380]);
+for(int i=offset+(1<<14)-1-16383;i>=offset+(1<<14)-16384;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-0;i>=offset-12288;--i)xorEq(poly[i],poly[i+12288],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-12288;i>=offset-15360;--i)xorEq(poly[i],poly[i+15360],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-15360;i>=offset-16128;--i)xorEq(poly[i],poly[i+16128],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-16128;i>=offset-16320;--i)xorEq(poly[i],poly[i+16320],poly[i+16368],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-16320;i>=offset-16368;--i)xorEq(poly[i],poly[i+16368],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-16368;i>=offset-16380;--i)xorEq(poly[i],poly[i+16380],poly[i+16383]);
+for(int i=offset-1-16380;i>=offset-16383;--i)xorEq(poly[i],poly[i+16383]);
+
+}
+for(int offset=(1<<13);offset<(1<=offset+(1<<13)-7680;--i)xorEq(poly[i],poly[i+4096]);
+for(int i=offset+(1<<13)-1-7680;i>=offset+(1<<13)-7936;--i)xorEq(poly[i],poly[i+4096],poly[i+7680]);
+for(int i=offset+(1<<13)-1-7936;i>=offset+(1<<13)-8160;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936]);
+for(int i=offset+(1<<13)-1-8160;i>=offset+(1<<13)-8176;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160]);
+for(int i=offset+(1<<13)-1-8176;i>=offset+(1<<13)-8190;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176]);
+for(int i=offset+(1<<13)-1-8190;i>=offset+(1<<13)-8191;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190]);
+for(int i=offset+(1<<13)-1-8191;i>=offset+(1<<13)-8192;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-0;i>=offset-4096;--i)xorEq(poly[i],poly[i+4096],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-4096;i>=offset-7680;--i)xorEq(poly[i],poly[i+7680],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-7680;i>=offset-7936;--i)xorEq(poly[i],poly[i+7936],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-7936;i>=offset-8160;--i)xorEq(poly[i],poly[i+8160],poly[i+8176],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-8160;i>=offset-8176;--i)xorEq(poly[i],poly[i+8176],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-8176;i>=offset-8190;--i)xorEq(poly[i],poly[i+8190],poly[i+8191]);
+for(int i=offset-1-8190;i>=offset-8191;--i)xorEq(poly[i],poly[i+8191]);
+
+}
+for(int offset=(1<<12);offset<(1<=offset+(1<<12)-4080;--i)xorEq(poly[i],poly[i+3840]);
+for(int i=offset+(1<<12)-1-4080;i>=offset+(1<<12)-4095;--i)xorEq(poly[i],poly[i+3840],poly[i+4080]);
+for(int i=offset+(1<<12)-1-4095;i>=offset+(1<<12)-4096;--i)xorEq(poly[i],poly[i+3840],poly[i+4080],poly[i+4095]);
+for(int i=offset-1-0;i>=offset-3840;--i)xorEq(poly[i],poly[i+3840],poly[i+4080],poly[i+4095]);
+for(int i=offset-1-3840;i>=offset-4080;--i)xorEq(poly[i],poly[i+4080],poly[i+4095]);
+for(int i=offset-1-4080;i>=offset-4095;--i)xorEq(poly[i],poly[i+4095]);
+
+}
+for(int offset=(1<<11);offset<(1<=offset+(1<<11)-1536;--i)xorEq(poly[i],poly[i+1024]);
+for(int i=offset+(1<<11)-1-1536;i>=offset+(1<<11)-1792;--i)xorEq(poly[i],poly[i+1024],poly[i+1536]);
+for(int i=offset+(1<<11)-1-1792;i>=offset+(1<<11)-2040;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792]);
+for(int i=offset+(1<<11)-1-2040;i>=offset+(1<<11)-2044;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040]);
+for(int i=offset+(1<<11)-1-2044;i>=offset+(1<<11)-2046;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044]);
+for(int i=offset+(1<<11)-1-2046;i>=offset+(1<<11)-2047;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046]);
+for(int i=offset+(1<<11)-1-2047;i>=offset+(1<<11)-2048;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-0;i>=offset-1024;--i)xorEq(poly[i],poly[i+1024],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-1024;i>=offset-1536;--i)xorEq(poly[i],poly[i+1536],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-1536;i>=offset-1792;--i)xorEq(poly[i],poly[i+1792],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-1792;i>=offset-2040;--i)xorEq(poly[i],poly[i+2040],poly[i+2044],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-2040;i>=offset-2044;--i)xorEq(poly[i],poly[i+2044],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-2044;i>=offset-2046;--i)xorEq(poly[i],poly[i+2046],poly[i+2047]);
+for(int i=offset-1-2046;i>=offset-2047;--i)xorEq(poly[i],poly[i+2047]);
+
+}
+for(int offset=(1<<10);offset<(1<=offset+(1<<10)-1020;--i)xorEq(poly[i],poly[i+768]);
+for(int i=offset+(1<<10)-1-1020;i>=offset+(1<<10)-1023;--i)xorEq(poly[i],poly[i+768],poly[i+1020]);
+for(int i=offset+(1<<10)-1-1023;i>=offset+(1<<10)-1024;--i)xorEq(poly[i],poly[i+768],poly[i+1020],poly[i+1023]);
+for(int i=offset-1-0;i>=offset-768;--i)xorEq(poly[i],poly[i+768],poly[i+1020],poly[i+1023]);
+for(int i=offset-1-768;i>=offset-1020;--i)xorEq(poly[i],poly[i+1020],poly[i+1023]);
+for(int i=offset-1-1020;i>=offset-1023;--i)xorEq(poly[i],poly[i+1023]);
+
+}
+for(int offset=(1<<9);offset<(1<=offset+(1<<9)-510;--i)xorEq(poly[i],poly[i+256]);
+for(int i=offset+(1<<9)-1-510;i>=offset+(1<<9)-511;--i)xorEq(poly[i],poly[i+256],poly[i+510]);
+for(int i=offset+(1<<9)-1-511;i>=offset+(1<<9)-512;--i)xorEq(poly[i],poly[i+256],poly[i+510],poly[i+511]);
+for(int i=offset-1-0;i>=offset-256;--i)xorEq(poly[i],poly[i+256],poly[i+510],poly[i+511]);
+for(int i=offset-1-256;i>=offset-510;--i)xorEq(poly[i],poly[i+510],poly[i+511]);
+for(int i=offset-1-510;i>=offset-511;--i)xorEq(poly[i],poly[i+511]);
+
+}
+for(int offset=(1<<8);offset<(1<=offset+(1<<8)-256;--i)xorEq(poly[i],poly[i+255]);
+for(int i=offset-1-0;i>=offset-255;--i)xorEq(poly[i],poly[i+255]);
+
+}
+for(int offset=(1<<7);offset<(1<=offset+(1<<7)-96;--i)xorEq(poly[i],poly[i+64]);
+for(int i=offset+(1<<7)-1-96;i>=offset+(1<<7)-112;--i)xorEq(poly[i],poly[i+64],poly[i+96]);
+for(int i=offset+(1<<7)-1-112;i>=offset+(1<<7)-120;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112]);
+for(int i=offset+(1<<7)-1-120;i>=offset+(1<<7)-124;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120]);
+for(int i=offset+(1<<7)-1-124;i>=offset+(1<<7)-126;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124]);
+for(int i=offset+(1<<7)-1-126;i>=offset+(1<<7)-127;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126]);
+for(int i=offset+(1<<7)-1-127;i>=offset+(1<<7)-128;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]);
+for(int i=offset-1-0;i>=offset-64;--i)xorEq(poly[i],poly[i+64],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]);
+for(int i=offset-1-64;i>=offset-96;--i)xorEq(poly[i],poly[i+96],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]);
+for(int i=offset-1-96;i>=offset-112;--i)xorEq(poly[i],poly[i+112],poly[i+120],poly[i+124],poly[i+126],poly[i+127]);
+for(int i=offset-1-112;i>=offset-120;--i)xorEq(poly[i],poly[i+120],poly[i+124],poly[i+126],poly[i+127]);
+for(int i=offset-1-120;i>=offset-124;--i)xorEq(poly[i],poly[i+124],poly[i+126],poly[i+127]);
+for(int i=offset-1-124;i>=offset-126;--i)xorEq(poly[i],poly[i+126],poly[i+127]);
+for(int i=offset-1-126;i>=offset-127;--i)xorEq(poly[i],poly[i+127]);
+
+}
+for(int offset=(1<<6);offset<(1<=offset+(1<<6)-60;--i)xorEq(poly[i],poly[i+48]);
+for(int i=offset+(1<<6)-1-60;i>=offset+(1<<6)-63;--i)xorEq(poly[i],poly[i+48],poly[i+60]);
+for(int i=offset+(1<<6)-1-63;i>=offset+(1<<6)-64;--i)xorEq(poly[i],poly[i+48],poly[i+60],poly[i+63]);
+for(int i=offset-1-0;i>=offset-48;--i)xorEq(poly[i],poly[i+48],poly[i+60],poly[i+63]);
+for(int i=offset-1-48;i>=offset-60;--i)xorEq(poly[i],poly[i+60],poly[i+63]);
+for(int i=offset-1-60;i>=offset-63;--i)xorEq(poly[i],poly[i+63]);
+
+}
+for(int offset=(1<<5);offset<(1<=offset+(1<<5)-30;--i)xorEq(poly[i],poly[i+16]);
+for(int i=offset+(1<<5)-1-30;i>=offset+(1<<5)-31;--i)xorEq(poly[i],poly[i+16],poly[i+30]);
+for(int i=offset+(1<<5)-1-31;i>=offset+(1<<5)-32;--i)xorEq(poly[i],poly[i+16],poly[i+30],poly[i+31]);
+for(int i=offset-1-0;i>=offset-16;--i)xorEq(poly[i],poly[i+16],poly[i+30],poly[i+31]);
+for(int i=offset-1-16;i>=offset-30;--i)xorEq(poly[i],poly[i+30],poly[i+31]);
+for(int i=offset-1-30;i>=offset-31;--i)xorEq(poly[i],poly[i+31]);
+
+}
+for(int offset=(1<<4);offset<(1<=offset+(1<<4)-16;--i)xorEq(poly[i],poly[i+15]);
+for(int i=offset-1-0;i>=offset-15;--i)xorEq(poly[i],poly[i+15]);
+
+}
+for(int offset=(1<<3);offset<(1<=offset+(1<<3)-6;--i)xorEq(poly[i],poly[i+4]);
+for(int i=offset+(1<<3)-1-6;i>=offset+(1<<3)-7;--i)xorEq(poly[i],poly[i+4],poly[i+6]);
+for(int i=offset+(1<<3)-1-7;i>=offset+(1<<3)-8;--i)xorEq(poly[i],poly[i+4],poly[i+6],poly[i+7]);
+for(int i=offset-1-0;i>=offset-4;--i)xorEq(poly[i],poly[i+4],poly[i+6],poly[i+7]);
+for(int i=offset-1-4;i>=offset-6;--i)xorEq(poly[i],poly[i+6],poly[i+7]);
+for(int i=offset-1-6;i>=offset-7;--i)xorEq(poly[i],poly[i+7]);
+
+}
+for(int offset=(1<<2);offset<(1<=offset+(1<<2)-4;--i)xorEq(poly[i],poly[i+3]);
+for(int i=offset-1-0;i>=offset-3;--i)xorEq(poly[i],poly[i+3]);
+
+}
+for(int offset=(1<<1);offset<(1<=offset+(1<<1)-2;--i)xorEq(poly[i],poly[i+1]);
+for(int i=offset-1-0;i>=offset-1;--i)xorEq(poly[i],poly[i+1]);
+
+}
+}
+}
diff --git a/bitpolymul/bc_to_mono_gen_code.cpp b/bitpolymul/bc_to_mono_gen_code.cpp
new file mode 100644
index 0000000..ed09355
--- /dev/null
+++ b/bitpolymul/bc_to_mono_gen_code.cpp
@@ -0,0 +1,480 @@
+/*
+Copyright (C) 2018 Wen-Ding Li
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+//#pragma message("here ------------------------------");
+
+#include "bc_to_gen_code.h"
+namespace bpm{
+void bc_to_mono_256_16(__m256i* poly, int logn){
+for(int offset=(1<<1);offset<(1<.
+*/
+
+#include
+#include
+#include
+
+#include "transpose.h"
+
+namespace bpm {
+
+
+ inline
+ __m128i bitmat_prod_accu_64x128_M8R_sse(__m128i r0, const uint64_t* mat4R, uint64_t a)
+ {
+ const __m128i* mat128 = (const __m128i*)mat4R;
+ while (a) {
+ r0 = _mm_xor_si128(r0, _mm_load_si128(mat128 + (a & 0xff)));
+ mat128 += 256;
+ a >>= 8;
+ }
+ return r0;
+ }
+
+ inline
+ void bitmatrix_prod_64x128_8R_sse(uint8_t* r, const uint64_t* mat4R, uint64_t a)
+ {
+ __m128i r0 = _mm_setzero_si128();
+ r0 = bitmat_prod_accu_64x128_M8R_sse(r0, mat4R, a);
+ _mm_store_si128((__m128i*) r, r0);
+ }
+
+
+ //USED;
+ inline
+ void bitmatrix_prod_128x128_4R_b32_opt_avx2(uint8_t* r32, const uint64_t* matB4R, const uint8_t* a32)
+ {
+ alignas(32) uint8_t t32[32 * 16];
+ tr_16x16_b2_avx2(t32, a32);
+
+ __m256i* r = (__m256i*) r32;
+ const __m256i* tab = (const __m256i*) & matB4R[0];
+ __m256i _0xf = _mm256_set1_epi8(0xf);
+
+ for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 16; i++) {
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ for (unsigned j = 0; j < 8; j++) {
+ __m256i tab_0 = tab[i * 16 + (j << 1)];
+ __m256i tab_1 = tab[i * 16 + (j << 1) + 1];
+ r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ }
+ }
+ tab += 16 * 16;
+ r += 8;
+ for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 16; i++) {
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ for (unsigned j = 0; j < 8; j++) {
+ __m256i tab_0 = tab[i * 16 + (j << 1)];
+ __m256i tab_1 = tab[i * 16 + (j << 1) + 1];
+ r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ }
+ }
+
+ tr_16x16_b2_avx2(r32, r32);
+ }
+
+
+ //USED;
+ inline
+ void bitmatrix_prod_64x128_4R_b32_opt_avx2(uint8_t* r128_32, const uint64_t* matB4R, const uint8_t* a64_32)
+ {
+ alignas(32) uint8_t t32[32 * 8];
+ /// 0x10,0x11,0x12,.....0x2f
+ transpose_8x8_b4_avx2(t32, a64_32);
+ /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, |
+ /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f,
+
+ __m256i* r = (__m256i*) r128_32;
+ const __m256i* tab = (const __m256i*) & matB4R[0];
+ __m256i _0xf = _mm256_set1_epi8(0xf);
+
+ for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 8; i++) { ///
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ for (unsigned j = 0; j < 8; j++) {
+ __m256i tab_0 = tab[i * 16 + (j << 1)];
+ __m256i tab_1 = tab[i * 16 + (j << 1) + 1];
+ r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ }
+ }
+ tab += 16 * 16;
+ r += 8;
+ for (unsigned i = 0; i < 8; i++) r[i] = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 8; i++) { ///
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ for (unsigned j = 0; j < 8; j++) {
+ __m256i tab_0 = tab[i * 16 + (j << 1)];
+ __m256i tab_1 = tab[i * 16 + (j << 1) + 1];
+ r[j] = _mm256_xor_si256(_mm256_xor_si256(r[j], _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ }
+ }
+
+ /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, |
+ /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f,
+ tr_16x16_b2_avx2(r128_32, r128_32);
+ /// 0x10,0x12,0x14,....,0x2e,0x11,0x13,0x15,....,0x2d,0x2f
+ }
+
+
+
+ inline
+ void bitmatrix_prod_64x64_4R_b64_avx2(uint8_t* r128_32, const uint64_t* matB4R, const uint8_t* a64_32)
+ {
+#if 0
+ bitmatrix_prod_64x64_4R_b32_avx2(r128_32, matB4R, a64_32);
+ bitmatrix_prod_64x64_4R_b32_avx2(r128_32 + 8 * 32, matB4R, a64_32 + 8 * 32);
+#else
+ alignas(32) uint8_t t32[32 * 8];
+ alignas(32) uint8_t u32[32 * 8];
+
+ /// 0x10,0x11,0x12,.....0x2f
+ transpose_8x8_b4_avx2(t32, a64_32);
+ transpose_8x8_b4_avx2(u32, a64_32 + 8 * 32);
+ /// bitsliced: 0x10,0x14,0x18,0x1c, 0x20,0x24,0x28,0x2c, 0x11,0x15,0x19,0x1d, 0x21,0x25,0x29,0x2d, |
+ /// 0x12,0x16,0x1a,0x1e, 0x22,0x26,0x2a,0x2e, 0x13,0x17,0x1b,0x1f, 0x23,0x27,0x2b,0x2f,
+
+ const __m256i* tab = (const __m256i*) & matB4R[0];
+ __m256i _0xf = _mm256_set1_epi8(0xf);
+
+ __m256i r0 = _mm256_setzero_si256();
+ __m256i r1 = _mm256_setzero_si256();
+ __m256i r2 = _mm256_setzero_si256();
+ __m256i r3 = _mm256_setzero_si256();
+ __m256i r4 = _mm256_setzero_si256();
+ __m256i r5 = _mm256_setzero_si256();
+ __m256i r6 = _mm256_setzero_si256();
+ __m256i r7 = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 8; i++) { ///
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i _0_low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i _0_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ __m256i temp1 = _mm256_load_si256((__m256i*)(u32 + i * 32));
+ __m256i _1_low1_low0 = _mm256_and_si256(temp1, _0xf);
+ __m256i _1_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp1), 4);
+
+ __m256i tab_0 = tab[i * 16];
+ __m256i tab_1 = tab[i * 16 + 1];
+ r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ tab_0 = tab[i * 16 + 2];
+ tab_1 = tab[i * 16 + 3];
+ r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ tab_0 = tab[i * 16 + 4];
+ tab_1 = tab[i * 16 + 5];
+ r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ tab_0 = tab[i * 16 + 6];
+ tab_1 = tab[i * 16 + 7];
+ r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ }
+ _mm256_store_si256((__m256i*)(r128_32 + 0), r0);
+ _mm256_store_si256((__m256i*)(r128_32 + 1 * 32), r1);
+ _mm256_store_si256((__m256i*)(r128_32 + 2 * 32), r2);
+ _mm256_store_si256((__m256i*)(r128_32 + 3 * 32), r3);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 0 * 32), r4);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 1 * 32), r5);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 2 * 32), r6);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 3 * 32), r7);
+
+ r0 = _mm256_setzero_si256();
+ r1 = _mm256_setzero_si256();
+ r2 = _mm256_setzero_si256();
+ r3 = _mm256_setzero_si256();
+ r4 = _mm256_setzero_si256();
+ r5 = _mm256_setzero_si256();
+ r6 = _mm256_setzero_si256();
+ r7 = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 8; i++) { ///
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i _0_low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i _0_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ __m256i temp1 = _mm256_load_si256((__m256i*)(u32 + i * 32));
+ __m256i _1_low1_low0 = _mm256_and_si256(temp1, _0xf);
+ __m256i _1_high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp1), 4);
+
+ __m256i tab_0 = tab[i * 16 + 8];
+ __m256i tab_1 = tab[i * 16 + 8 + 1];
+ r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ tab_0 = tab[i * 16 + 8 + 2];
+ tab_1 = tab[i * 16 + 8 + 3];
+ r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ tab_0 = tab[i * 16 + 8 + 4];
+ tab_1 = tab[i * 16 + 8 + 5];
+ r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ tab_0 = tab[i * 16 + 8 + 6];
+ tab_1 = tab[i * 16 + 8 + 7];
+ r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, _0_low1_low0)), _mm256_shuffle_epi8(tab_1, _0_high1_high0));
+ r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _1_low1_low0)), _mm256_shuffle_epi8(tab_1, _1_high1_high0));
+ }
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 0), r0);
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 1 * 32), r1);
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 2 * 32), r2);
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 3 * 32), r3);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 0 * 32), r4);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 1 * 32), r5);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 2 * 32), r6);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 3 * 32), r7);
+
+ transpose_8x8_b4_avx2(r128_32, r128_32);
+ transpose_8x8_b4_avx2(r128_32 + 8 * 32, r128_32 + 8 * 32);
+#endif
+ }
+
+
+ inline
+ void bitmatrix_prod_64x64_h32zero_4R_b64_avx2(uint8_t* r128_32, const uint64_t* matB4R, const uint8_t* a64_32)
+ {
+ alignas(32) uint8_t t32[32 * 8];
+ transpose_8x8_h4zero_b4_avx2(t32, a64_32);
+ transpose_8x8_h4zero_b4_avx2(t32 + 32 * 4, a64_32 + 32 * 8);
+
+ const __m256i* tab = (const __m256i*) & matB4R[0];
+ __m256i _0xf = _mm256_set1_epi8(0xf);
+
+ __m256i r0, r1, r2, r3, r4, r5, r6, r7;
+ r0 = _mm256_setzero_si256();
+ r1 = _mm256_setzero_si256();
+ r2 = _mm256_setzero_si256();
+ r3 = _mm256_setzero_si256();
+ r4 = _mm256_setzero_si256();
+ r5 = _mm256_setzero_si256();
+ r6 = _mm256_setzero_si256();
+ r7 = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 4; i++) { ///
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ __m256i _temp = _mm256_load_si256((__m256i*)(t32 + 4 * 32 + i * 32));
+ __m256i _low1_low0 = _mm256_and_si256(_temp, _0xf);
+ __m256i _high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, _temp), 4);
+
+ __m256i tab_0 = tab[i * 16 + 0 * 2];
+ __m256i tab_1 = tab[i * 16 + 0 * 2 + 1];
+ r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ tab_0 = tab[i * 16 + 1 * 2];
+ tab_1 = tab[i * 16 + 1 * 2 + 1];
+ r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ tab_0 = tab[i * 16 + 2 * 2];
+ tab_1 = tab[i * 16 + 2 * 2 + 1];
+ r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ tab_0 = tab[i * 16 + 3 * 2];
+ tab_1 = tab[i * 16 + 3 * 2 + 1];
+ r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ }
+ _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 0), r0);
+ _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 1 * 32), r1);
+ _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 2 * 32), r2);
+ _mm256_store_si256((__m256i*)(r128_32 + 0 * 32 + 3 * 32), r3);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 0 * 32), r4);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 1 * 32), r5);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 2 * 32), r6);
+ _mm256_store_si256((__m256i*)(r128_32 + 8 * 32 + 3 * 32), r7);
+
+ r0 = _mm256_setzero_si256();
+ r1 = _mm256_setzero_si256();
+ r2 = _mm256_setzero_si256();
+ r3 = _mm256_setzero_si256();
+ r4 = _mm256_setzero_si256();
+ r5 = _mm256_setzero_si256();
+ r6 = _mm256_setzero_si256();
+ r7 = _mm256_setzero_si256();
+ for (unsigned i = 0; i < 4; i++) { ///
+ __m256i temp = _mm256_load_si256((__m256i*)(t32 + i * 32));
+ __m256i low1_low0 = _mm256_and_si256(temp, _0xf);
+ __m256i high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, temp), 4);
+
+ __m256i _temp = _mm256_load_si256((__m256i*)(t32 + 4 * 32 + i * 32));
+ __m256i _low1_low0 = _mm256_and_si256(_temp, _0xf);
+ __m256i _high1_high0 = _mm256_srli_epi16(_mm256_andnot_si256(_0xf, _temp), 4);
+
+ __m256i tab_0 = tab[i * 16 + 4 * 2];
+ __m256i tab_1 = tab[i * 16 + 4 * 2 + 1];
+ r0 = _mm256_xor_si256(_mm256_xor_si256(r0, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r4 = _mm256_xor_si256(_mm256_xor_si256(r4, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ tab_0 = tab[i * 16 + 5 * 2];
+ tab_1 = tab[i * 16 + 5 * 2 + 1];
+ r1 = _mm256_xor_si256(_mm256_xor_si256(r1, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r5 = _mm256_xor_si256(_mm256_xor_si256(r5, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ tab_0 = tab[i * 16 + 6 * 2];
+ tab_1 = tab[i * 16 + 6 * 2 + 1];
+ r2 = _mm256_xor_si256(_mm256_xor_si256(r2, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r6 = _mm256_xor_si256(_mm256_xor_si256(r6, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ tab_0 = tab[i * 16 + 7 * 2];
+ tab_1 = tab[i * 16 + 7 * 2 + 1];
+ r3 = _mm256_xor_si256(_mm256_xor_si256(r3, _mm256_shuffle_epi8(tab_0, low1_low0)), _mm256_shuffle_epi8(tab_1, high1_high0));
+ r7 = _mm256_xor_si256(_mm256_xor_si256(r7, _mm256_shuffle_epi8(tab_0, _low1_low0)), _mm256_shuffle_epi8(tab_1, _high1_high0));
+ }
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 0), r0);
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 1 * 32), r1);
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 2 * 32), r2);
+ _mm256_store_si256((__m256i*)(r128_32 + 4 * 32 + 3 * 32), r3);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 0 * 32), r4);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 1 * 32), r5);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 2 * 32), r6);
+ _mm256_store_si256((__m256i*)(r128_32 + 12 * 32 + 3 * 32), r7);
+
+ transpose_8x8_b4_avx2(r128_32, r128_32);
+ transpose_8x8_b4_avx2(r128_32 + 32 * 8, r128_32 + 32 * 8);
+ }
+
+}
+
+
diff --git a/bitpolymul/bitpolymul.cpp b/bitpolymul/bitpolymul.cpp
new file mode 100644
index 0000000..5bfc720
--- /dev/null
+++ b/bitpolymul/bitpolymul.cpp
@@ -0,0 +1,194 @@
+#include "bitpolymul.h"
+#include
+#include
+#include
+#include
+#include
+
+#include "bitpolymul/bc.h"
+#include "bitpolymul/gfext_aesni.h"
+#include "bitpolymul/bpmDefines.h"
+#include "bitpolymul/btfy.h"
+#include "bitpolymul/encode.h"
+
+
+namespace bpm
+{
+
+ struct Aligned
+ {
+ std::unique_ptr uPtr;
+ u64* ptr;
+ u64* data()
+ {
+ return ptr;
+ }
+
+ u64& operator[](u64 i)
+ {
+ return data()[i];
+ }
+ };
+
+ Aligned alignedNew(u64 n)
+ {
+ u64 aligment = sizeof(__m256);
+ std::unique_ptr uPtr(new u64[n + aligment]);
+ u8* u8ptr = (u8*)uPtr.get();
+
+ auto offset = u64(u8ptr) % aligment;
+ if (offset)
+ u8ptr += aligment - offset;
+
+ return Aligned{ std::move(uPtr), (u64*)u8ptr };
+ }
+
+ const int tab64[64] = {
+ 63, 0, 58, 1, 59, 47, 53, 2,
+ 60, 39, 48, 27, 54, 33, 42, 3,
+ 61, 51, 37, 40, 49, 18, 28, 20,
+ 55, 30, 34, 11, 43, 14, 22, 4,
+ 62, 57, 46, 52, 38, 26, 32, 41,
+ 50, 36, 17, 19, 29, 10, 13, 21,
+ 56, 45, 25, 31, 35, 16, 9, 12,
+ 44, 24, 15, 8, 23, 7, 6, 5 };
+
+
+ u64 log2floor(u64 value)
+ {
+ value |= value >> 1;
+ value |= value >> 2;
+ value |= value >> 4;
+ value |= value >> 8;
+ value |= value >> 16;
+ value |= value >> 32;
+ return tab64[((uint64_t)((value - (value >> 1)) * 0x07EDD5E59A4E28C2)) >> 58];
+ }
+
+ u64 log2ceil(u64 value)
+ {
+ auto floor = log2floor(value);
+ return floor + (value > (1ull << floor));
+ }
+
+ void bitpolymul_2_128(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 _n_64)
+ {
+ if (0 == _n_64) return;
+ u64 n_64 = 0;
+ if (1 == _n_64)
+ n_64 = _n_64;
+ else {
+ n_64 = 1ull << log2ceil(_n_64);
+ }
+
+ if (256 > n_64) n_64 = 256;
+
+ auto a_bc = alignedNew(n_64);
+ auto b_bc = alignedNew(n_64);
+
+ memcpy(a_bc.data(), a, sizeof(uint64_t) * _n_64);
+ for (u64 i = _n_64; i < n_64; i++) a_bc[i] = 0;
+ bc_to_lch_2_unit256(a_bc.data(), n_64);
+
+ memcpy(b_bc.data(), b, sizeof(uint64_t) * _n_64);
+ for (u64 i = _n_64; i < n_64; i++) b_bc[i] = 0;
+ bc_to_lch_2_unit256(b_bc.data(), n_64);
+
+
+ u64 n_terms = n_64;
+ u64 log_n = __builtin_ctzll(n_terms);
+ auto a_fx = alignedNew(2 * n_terms);
+ auto b_fx = alignedNew(2 * n_terms);
+
+ encode_128_half_input_zero(a_fx.data(), a_bc.data(), n_terms);
+ encode_128_half_input_zero(b_fx.data(), b_bc.data(), n_terms);
+
+ btfy_128(b_fx.data(), n_terms, 64 + log_n + 1);
+ btfy_128(a_fx.data(), n_terms, 64 + log_n + 1);
+
+ for (u64 i = 0; i < n_terms; i++)
+ {
+ gf2ext128_mul_sse(
+ (uint8_t*)& a_fx[i * 2],
+ (uint8_t*)& a_fx[i * 2],
+ (uint8_t*)& b_fx[i * 2]);
+ }
+
+ i_btfy_128(a_fx.data(), n_terms, 64 + log_n + 1);
+
+ decode_128(b_fx.data(), a_fx.data(), n_terms);
+
+ bc_to_mono_2_unit256(b_fx.data(), 2 * n_64);
+
+ for (u64 i = 0; i < (2 * _n_64); i++) {
+ c[i] = b_fx[i];
+ }
+
+ }
+
+
+
+
+
+
+ ///////////////////////////////////////////////////
+
+
+ void bitpolymul_2_64(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 _n_64)
+ {
+ if (0 == _n_64) return;
+ if (_n_64 > (1 << 26)) { printf("un-supported length of polynomials."); exit(-1); }
+ u64 n_64 = 0;
+ if (1 == _n_64) n_64 = _n_64;
+ else {
+ n_64 = 1ull << log2ceil(_n_64);
+ }
+
+ if (256 > n_64) n_64 = 256;
+
+
+
+ auto a_bc_ = alignedNew(n_64);
+ auto b_bc_ = alignedNew(n_64);
+ uint64_t* a_bc = a_bc_.data();
+ uint64_t* b_bc = b_bc_.data();
+
+ memcpy(a_bc, a, sizeof(uint64_t) * _n_64);
+ for (u64 i = _n_64; i < n_64; i++) a_bc[i] = 0;
+ bc_to_lch_2_unit256(a_bc, n_64);
+
+ memcpy(b_bc, b, sizeof(uint64_t) * _n_64);
+ for (u64 i = _n_64; i < n_64; i++) b_bc[i] = 0;
+ bc_to_lch_2_unit256(b_bc, n_64);
+
+
+ u64 n_terms = n_64 * 2;
+ u64 log_n = __builtin_ctzll(n_terms);
+
+ auto a_fx_ = alignedNew(n_terms);
+ auto b_fx_ = alignedNew(n_terms);
+ uint64_t* a_fx = a_fx_.data();
+ uint64_t* b_fx = b_fx_.data();
+
+ encode_64_half_input_zero(a_fx, a_bc, n_terms);
+ encode_64_half_input_zero(b_fx, b_bc, n_terms);
+
+ btfy_64(b_fx, n_terms, 32 + log_n + 1);
+ btfy_64(a_fx, n_terms, 32 + log_n + 1);
+
+ for (u64 i = 0; i < n_terms; i += 4) {
+ cache_prefetch(&a_fx[i + 4], _MM_HINT_T0);
+ cache_prefetch(&b_fx[i + 4], _MM_HINT_T0);
+ gf2ext64_mul_4x4_avx2((uint8_t*)& a_fx[i], (uint8_t*)& a_fx[i], (uint8_t*)& b_fx[i]);
+ }
+ i_btfy_64(a_fx, n_terms, 32 + log_n + 1);
+ decode_64(b_fx, a_fx, n_terms);
+
+ bc_to_mono_2_unit256(b_fx, n_terms);
+
+ for (u64 i = 0; i < (2 * _n_64); i++) {
+ c[i] = b_fx[i];
+ }
+ }
+
+}
diff --git a/gf264_cantor_iso.h b/bitpolymul/bitpolymul.h
similarity index 74%
rename from gf264_cantor_iso.h
rename to bitpolymul/bitpolymul.h
index 37d0511..f31955d 100644
--- a/gf264_cantor_iso.h
+++ b/bitpolymul/bitpolymul.h
@@ -1,3 +1,4 @@
+#pragma once
/*
Copyright (C) 2017 Ming-Shing Chen
@@ -17,26 +18,17 @@ You should have received a copy of the GNU Lesser General Public License
along with BitPolyMul. If not, see .
*/
-#ifndef _GF264_CANTOR_ISO_H_
-#define _GF264_CANTOR_ISO_H_
-#include
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern uint64_t gfCantorto264[];
-
-extern uint64_t gfCantorto264_8R[];
+#include
+#include
+#include "bpmDefines.h"
+namespace bpm
+{
+ void bitpolymul_2_128(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 n_64);
+ void bitpolymul_2_64(uint64_t* c, const uint64_t* a, const uint64_t* b, u64 n_64);
-#ifdef __cplusplus
}
-#endif
-
-#endif
diff --git a/bitpolymul/bpmDefines.h b/bitpolymul/bpmDefines.h
new file mode 100644
index 0000000..a47c628
--- /dev/null
+++ b/bitpolymul/bpmDefines.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include
+#include
+
+
+#include
+#include
+#include
+#ifdef _MSC_VER
+#include
+#include
+#endif
+
+//#define (x)
+namespace bpm
+{
+
+ using u64 = std::uint64_t;
+ using u32 = std::uint32_t;
+ using u16 = std::uint16_t;
+ using u8 = std::uint8_t;
+ using i64 = std::int64_t;
+ using i32 = std::int32_t;
+ using i16 = std::int16_t;
+ using i8 = std::int8_t;
+
+
+#ifdef _MSC_VER
+ inline int __builtin_ctz(uint32_t x) {
+ unsigned long ret;
+ _BitScanForward(&ret, x);
+ return (int)ret;
+ }
+
+ inline int __builtin_ctzll(unsigned long long x) {
+ unsigned long ret;
+ _BitScanForward64(&ret, x);
+ return (int)ret;
+ }
+
+
+
+ inline int __builtin_ctzl(unsigned long x) { return sizeof(x) == 8 ? __builtin_ctzll(x) : __builtin_ctz((uint32_t)x); }
+ inline int __builtin_clz(uint32_t x) { return (int)__lzcnt(x); }
+ inline int __builtin_clzll(unsigned long long x) { return (int)__lzcnt64(x); }
+ inline int __builtin_clzl(unsigned long x) { return sizeof(x) == 8 ? __builtin_clzll(x) : __builtin_clz((uint32_t)x); }
+
+ inline int __builtin_ctzl(unsigned long long x) { return __builtin_ctzll(x); }
+ inline int __builtin_clzl(unsigned long long x) { return __builtin_clzll(x); }
+
+#endif
+
+
+#define xor128(v1,v2) _mm_xor_si128(v1,v2)
+#define xor256(v1,v2) _mm256_xor_si256(v1,v2)
+#define and128(v1,v2) _mm_and_si128(v1,v2)
+#define and256(v1,v2) _mm256_and_si256(v1,v2)
+#define or128(v1,v2) _mm_or_si128(v1,v2)
+#define or256(v1,v2) _mm256_or_si256(v1,v2)
+
+
+#define cache_prefetch(d, p) _mm_prefetch((const char*)d, p)
+
+
+}
\ No newline at end of file
diff --git a/bitpolymul/btfy.cpp b/bitpolymul/btfy.cpp
new file mode 100644
index 0000000..33b0f1a
--- /dev/null
+++ b/bitpolymul/btfy.cpp
@@ -0,0 +1,1045 @@
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+#include
+
+#include "gfext_aesni.h"
+#include "string.h"
+
+#include "bpmDefines.h"
+
+#include "bitmat_prod.h"
+
+#include "gf2128_cantor_iso.h"
+#include "gf264_cantor_iso.h"
+
+/////////////////////////////////////////////////
+///
+/// field isomorphism. Cantor --> GF(2^128).
+///
+//////////////////////////////////////////////////////
+
+
+namespace bpm {
+
+ //USED;
+ inline
+ __m128i gf_isomorphism_single_bit(u64 ith_bit)
+ {
+ return _mm_load_si128((__m128i*) (&gfCantorto2128[ith_bit]));
+ }
+
+ //USED;
+ inline
+ __m128i gf_isomorphism(uint64_t a_in_cantor)
+ {
+ alignas(32) uint8_t a_iso[16];
+ bitmatrix_prod_64x128_8R_sse(a_iso, gfCantorto2128_8R, a_in_cantor);
+ return _mm_load_si128((__m128i*) a_iso);
+ }
+
+
+
+ /////////////////////////////////////////////////
+ ///
+ /// Butterfly network. pclmulqdq version.
+ ///
+ //////////////////////////////////////////////////////
+
+
+
+ /////// one layer /////////////////////
+
+ //USED;
+ inline
+ __m128i butterfly(__m128i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i++) {
+ poly[i] = xor128(poly[i], _gf2ext128_mul_sse(poly[unit_2 + i], a));
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0);
+ poly[unit_2 + i] = xor128(poly[unit_2 + i], poly[i]);
+ }
+ return a;
+ }
+
+
+
+ //USED;
+ inline
+ __m128i butterfly_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i++) {
+ poly[i] = xor256(poly[i], _gf2ext128_mul_2x1_avx2(poly[unit_2 + i], a));
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0);
+ poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]);
+ }
+ return a;
+ }
+
+
+ //USED;
+ inline
+ __m128i butterfly_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 2) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+ cache_prefetch(&poly[i], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+
+ cache_prefetch(&poly[unit_2 + i + 2], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 3], _MM_HINT_T0);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ }
+ return a;
+ }
+
+
+ //USED;
+ inline
+ __m128i butterfly_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 4) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+ __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]);
+ __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]);
+ cache_prefetch(&poly[i], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 2], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 3], _MM_HINT_T0);
+ __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a);
+ __m256i ap2 = _gf2ext128_mul_2x1_avx2(p2, a);
+ __m256i ap3 = _gf2ext128_mul_2x1_avx2(p3, a);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+ __m256i q2 = _mm256_load_si256(&poly[i + 2]);
+ __m256i q3 = _mm256_load_si256(&poly[i + 3]);
+
+ cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ q2 = xor256(q2, ap2);
+ q3 = xor256(q3, ap3);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ _mm256_store_si256(&poly[i + 2], q2);
+ _mm256_store_si256(&poly[i + 3], q3);
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ p2 = xor256(p2, q2);
+ p3 = xor256(p3, q3);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ _mm256_store_si256(&poly[unit_2 + i + 2], p2);
+ _mm256_store_si256(&poly[unit_2 + i + 3], p3);
+ }
+ return a;
+ }
+
+
+
+
+ inline
+ __m128i i_butterfly(__m128i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i++) {
+ poly[unit_2 + i] = xor128(poly[unit_2 + i], poly[i]);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0);
+ poly[i] = xor128(poly[i], _gf2ext128_mul_sse(poly[unit_2 + i], a));
+ }
+ return a;
+ }
+
+
+
+ inline
+ __m128i i_butterfly_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i++) {
+ poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0);
+ poly[i] = xor256(poly[i], _gf2ext128_mul_2x1_avx2(poly[unit_2 + i], a));
+ }
+ return a;
+ }
+
+ inline
+ __m128i i_butterfly_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 2) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ cache_prefetch((const char*)& poly[i + 2], _MM_HINT_T0);
+ cache_prefetch((const char*)& poly[i + 3], _MM_HINT_T0);
+ cache_prefetch((const char*)& poly[unit_2 + i + 2], _MM_HINT_T0);
+ cache_prefetch((const char*)& poly[unit_2 + i + 3], _MM_HINT_T0);
+
+ __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ }
+ return a;
+ }
+
+
+
+ //USED;
+ inline
+ __m128i i_butterfly_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 4) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+ __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]);
+ __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+ __m256i q2 = _mm256_load_si256(&poly[i + 2]);
+ __m256i q3 = _mm256_load_si256(&poly[i + 3]);
+
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ p2 = xor256(p2, q2);
+ p3 = xor256(p3, q3);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ _mm256_store_si256(&poly[unit_2 + i + 2], p2);
+ _mm256_store_si256(&poly[unit_2 + i + 3], p3);
+ cache_prefetch(&poly[i + 4], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 5], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 6], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 7], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0);
+
+ __m256i ap0 = _gf2ext128_mul_2x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext128_mul_2x1_avx2(p1, a);
+ __m256i ap2 = _gf2ext128_mul_2x1_avx2(p2, a);
+ __m256i ap3 = _gf2ext128_mul_2x1_avx2(p3, a);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ q2 = xor256(q2, ap2);
+ q3 = xor256(q3, ap3);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ _mm256_store_si256(&poly[i + 2], q2);
+ _mm256_store_si256(&poly[i + 3], q3);
+ }
+ return a;
+ }
+
+
+ //////////////////////////////////////////////////////////////
+
+
+ //USED;
+ inline
+ void __btfy(uint64_t* fx, u64 st_unit_size, u64 offset, u64 n_terms, u64 scalar_a)
+ {
+
+ u64 i = st_unit_size;
+
+ __m256i* poly256 = (__m256i*) & fx[0];
+#if 1
+ for (; i > 3; i--) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = (offset >> 1) / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+ for (; i > 2; i--) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = (offset >> 1) / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_avx2_b2(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+#endif
+ for (; i > 1; i--) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = (offset >> 1) / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_avx2(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+ __m128i* poly128 = (__m128i*) & fx[0];
+ if (i > 0) {
+ u64 unit = (1ull << i);
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = offset / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly(poly128 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+ }
+
+
+ inline
+ void __i_btfy(uint64_t* fx, u64 end_unit_size, u64 offset, u64 n_terms, u64 scalar_a)
+ {
+ u64 i = 1;
+ __m128i* poly128 = (__m128i*) & fx[0];
+ for (; i < 2; i++) {
+ u64 unit = (1ull << i);
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = offset / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly(poly128 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+
+ __m256i* poly256 = (__m256i*) & fx[0];
+ for (; i < 3; i++) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = (offset >> 1) / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_avx2(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+ for (; i < 4; i++) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = (offset >> 1) / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_avx2_b2(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+
+ for (; i <= end_unit_size; i++) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ u64 st = (offset >> 1) / unit;
+ for (u64 j = st; j < st + num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+
+ }
+
+
+
+
+
+
+ /////////////////////////////////////////////////////
+ //
+ // Public functions.
+ //
+ /////////////////////////////////////////////////////
+
+
+
+
+#define _LOG_CACHE_SIZE_ 14
+
+
+ //USED;
+ void btfy_128(uint64_t * fx, u64 n_fx, u64 scalar_a)
+ {
+
+ if (1 >= n_fx) return;
+
+ u64 log_n = __builtin_ctzll(n_fx);
+ u64 n_terms = n_fx;
+
+ u64 i = log_n;
+
+ __m256i* poly256 = (__m256i*) & fx[0];
+ for (; i > _LOG_CACHE_SIZE_; i--) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+ //// i == 15 or less
+ u64 unit = (1ull << i);
+ u64 num = n_terms / unit;
+ for (u64 j = 0; j < num; j++) {
+ __btfy(fx, i, j * unit, unit, scalar_a);
+ }
+ }
+
+
+
+ //USED;
+ void i_btfy_128(uint64_t* fx, u64 n_fx, u64 scalar_a)
+ {
+ if (1 >= n_fx) return;
+
+ u64 log_n = __builtin_ctzll(n_fx);
+
+ u64 n_terms = n_fx;
+
+ {
+ u64 unit = ((1ull << _LOG_CACHE_SIZE_) > n_fx) ? n_fx : (1ull << _LOG_CACHE_SIZE_);
+ u64 num = n_terms / unit;
+ for (u64 j = 0; j < num; j++) { __i_btfy(fx, _LOG_CACHE_SIZE_, j * unit, unit, scalar_a); };
+ }
+ __m256i* poly256 = (__m256i*) & fx[0];
+ for (u64 i = _LOG_CACHE_SIZE_ + 1; i <= log_n; i++) {
+ u64 unit = (1ull << (i - 1));
+ u64 num = (n_terms >> 1) / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf_isomorphism_single_bit((scalar_a - k - 1) << 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_avx2_b4(poly256 + j * unit, unit, diff_j << 1, extra_a);
+ }
+ }
+
+ }
+
+
+
+
+
+ /////////////////////////////////////////////////////////////
+
+
+
+ inline
+ __m128i gf264_isomorphism_single_bit(u64 ith_bit)
+ {
+ return _mm_load_si128((__m128i*) (&gfCantorto264[ith_bit << 1]));
+ }
+
+ inline
+ __m128i gf264_isomorphism(uint64_t a_in_cantor)
+ {
+ alignas(32) uint8_t a_iso[16];
+ bitmatrix_prod_64x128_8R_sse(a_iso, gfCantorto264_8R, a_in_cantor);
+ return _mm_load_si128((__m128i*) a_iso);
+ }
+
+ ////////////////////////////////
+
+ inline
+ __m128i butterfly_64_xmm(__m128i d, __m128i a)
+ {
+ __m128i r0 = xor128(d, _gf2ext64_mul_hi_sse(d, a));
+ __m128i r1 = xor128(r0, _mm_slli_si128(r0, 8));
+ return r1;
+ }
+
+ inline
+ __m128i i_butterfly_64_xmm(__m128i d, __m128i a)
+ {
+ __m128i r0 = xor128(d, _mm_slli_si128(d, 8));
+ __m128i r1 = xor128(r0, _gf2ext64_mul_hi_sse(r0, a));
+ return r1;
+ }
+
+ inline
+ __m128i butterfly_64_u2(__m128i* poly, u64 ska, __m128i extra_a) /// unit = 2>>1
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+ poly[0] = butterfly_64_xmm(poly[0], a);
+ cache_prefetch(&poly[1], _MM_HINT_T0);
+ return a;
+ }
+
+ inline
+ __m128i i_butterfly_64_u2(__m128i* poly, u64 ska, __m128i extra_a) /// unit = 2>>1
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+ poly[0] = i_butterfly_64_xmm(poly[0], a);
+ cache_prefetch(&poly[1], _MM_HINT_T0);
+ return a;
+ }
+
+ ////////////////////////////
+
+
+ inline
+ __m256i butterfly_64_ymm(__m256i d, __m128i a)
+ {
+ __m128i d0 = _mm256_castsi256_si128(d);
+ __m128i d1 = _mm256_extracti128_si256(d, 1);
+ d0 = xor128(d0, _gf2ext64_mul_2x1_sse(d1, a));
+ d1 = xor128(d1, d0);
+ __m256i r0 = _mm256_castsi128_si256(d0);
+ __m256i r1 = _mm256_inserti128_si256(r0, d1, 1);
+ return r1;
+ }
+
+ inline
+ __m256i i_butterfly_64_ymm(__m256i d, __m128i a)
+ {
+ __m128i d0 = _mm256_castsi256_si128(d);
+ __m128i d1 = _mm256_extracti128_si256(d, 1);
+ d1 = xor128(d1, d0);
+ d0 = xor128(d0, _gf2ext64_mul_2x1_sse(d1, a));
+ __m256i r0 = _mm256_castsi128_si256(d0);
+ __m256i r1 = _mm256_inserti128_si256(r0, d1, 1);
+ return r1;
+ }
+
+ inline
+ __m128i butterfly_64_u4(__m256i* poly, u64 ska, __m128i extra_a) /// unit = 4>>2
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+ poly[0] = butterfly_64_ymm(poly[0], a);
+ cache_prefetch(&poly[1], _MM_HINT_T0);
+ return a;
+ }
+
+ inline
+ __m128i i_butterfly_64_u4(__m256i* poly, u64 ska, __m128i extra_a) /// unit = 4>>2
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+ poly[0] = i_butterfly_64_ymm(poly[0], a);
+ cache_prefetch(&poly[1], _MM_HINT_T0);
+ return a;
+ }
+
+
+ //////////////////////////////////////////////////
+
+
+ inline
+ __m128i butterfly_64_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a) /// unit >= 8>>2
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i++) {
+ poly[i] = xor256(poly[i], _gf2ext64_mul_4x1_avx2(poly[unit_2 + i], a));
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0);
+ poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]);
+ }
+ return a;
+ }
+
+
+ inline
+ __m128i butterfly_64_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 2) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+ cache_prefetch(&poly[i], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+
+ cache_prefetch(&poly[unit_2 + i + 2], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 3], _MM_HINT_T0);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ }
+ return a;
+ }
+
+
+ inline
+ __m128i butterfly_64_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 4) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+ __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]);
+ __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]);
+ cache_prefetch(&poly[i], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 2], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 3], _MM_HINT_T0);
+ __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a);
+ __m256i ap2 = _gf2ext64_mul_4x1_avx2(p2, a);
+ __m256i ap3 = _gf2ext64_mul_4x1_avx2(p3, a);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+ __m256i q2 = _mm256_load_si256(&poly[i + 2]);
+ __m256i q3 = _mm256_load_si256(&poly[i + 3]);
+
+ cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ q2 = xor256(q2, ap2);
+ q3 = xor256(q3, ap3);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ _mm256_store_si256(&poly[i + 2], q2);
+ _mm256_store_si256(&poly[i + 3], q3);
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ p2 = xor256(p2, q2);
+ p3 = xor256(p3, q3);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ _mm256_store_si256(&poly[unit_2 + i + 2], p2);
+ _mm256_store_si256(&poly[unit_2 + i + 3], p3);
+ }
+ return a;
+ }
+
+
+
+
+
+ inline
+ __m128i i_butterfly_64_avx2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i++) {
+ poly[unit_2 + i] = xor256(poly[unit_2 + i], poly[i]);
+ cache_prefetch(&poly[i + 1], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 1], _MM_HINT_T0);
+ poly[i] = xor256(poly[i], _gf2ext64_mul_4x1_avx2(poly[unit_2 + i], a));
+ }
+ return a;
+ }
+
+
+ inline
+ __m128i i_butterfly_64_avx2_b2(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 2) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ cache_prefetch(&poly[i + 2], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 3], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 2], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 3], _MM_HINT_T0);
+
+ __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ }
+ return a;
+ }
+
+
+
+ inline
+ __m128i i_butterfly_64_avx2_b4(__m256i* poly, u64 unit, u64 ska, __m128i extra_a)
+ {
+ __m128i a = extra_a;
+ a = xor128(a, gf264_isomorphism(ska));
+
+ u64 unit_2 = unit / 2;
+ for (u64 i = 0; i < unit_2; i += 4) {
+ __m256i p0 = _mm256_load_si256(&poly[unit_2 + i]);
+ __m256i p1 = _mm256_load_si256(&poly[unit_2 + i + 1]);
+ __m256i p2 = _mm256_load_si256(&poly[unit_2 + i + 2]);
+ __m256i p3 = _mm256_load_si256(&poly[unit_2 + i + 3]);
+
+ __m256i q0 = _mm256_load_si256(&poly[i]);
+ __m256i q1 = _mm256_load_si256(&poly[i + 1]);
+ __m256i q2 = _mm256_load_si256(&poly[i + 2]);
+ __m256i q3 = _mm256_load_si256(&poly[i + 3]);
+
+ p0 = xor256(p0, q0);
+ p1 = xor256(p1, q1);
+ p2 = xor256(p2, q2);
+ p3 = xor256(p3, q3);
+ _mm256_store_si256(&poly[unit_2 + i], p0);
+ _mm256_store_si256(&poly[unit_2 + i + 1], p1);
+ _mm256_store_si256(&poly[unit_2 + i + 2], p2);
+ _mm256_store_si256(&poly[unit_2 + i + 3], p3);
+ cache_prefetch(&poly[i + 4], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 5], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 6], _MM_HINT_T0);
+ cache_prefetch(&poly[i + 7], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 4], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 5], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 6], _MM_HINT_T0);
+ cache_prefetch(&poly[unit_2 + i + 7], _MM_HINT_T0);
+
+ __m256i ap0 = _gf2ext64_mul_4x1_avx2(p0, a);
+ __m256i ap1 = _gf2ext64_mul_4x1_avx2(p1, a);
+ __m256i ap2 = _gf2ext64_mul_4x1_avx2(p2, a);
+ __m256i ap3 = _gf2ext64_mul_4x1_avx2(p3, a);
+
+ q0 = xor256(q0, ap0);
+ q1 = xor256(q1, ap1);
+ q2 = xor256(q2, ap2);
+ q3 = xor256(q3, ap3);
+ _mm256_store_si256(&poly[i], q0);
+ _mm256_store_si256(&poly[i + 1], q1);
+ _mm256_store_si256(&poly[i + 2], q2);
+ _mm256_store_si256(&poly[i + 3], q3);
+ }
+ return a;
+ }
+
+
+
+ /////////////////////////////////////////////
+
+
+
+ void btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a)
+ {
+
+ if (1 >= n_fx) return;
+
+ u64 log_n = __builtin_ctzll(n_fx);
+ u64 n_terms = n_fx;
+
+ u64 i = log_n;
+
+ uint64_t* poly = fx;
+ for (; i > 4; i--) {
+ u64 unit = (1ull << i); /// u >= 8
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_64_avx2_b4((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a);
+ }
+ }
+ for (; i > 3; i--) {
+ u64 unit = (1ull << i); /// u >= 8
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_64_avx2_b2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a);
+ }
+ }
+ for (; i > 2; i--) {
+ u64 unit = (1ull << i); /// u >= 8
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_64_avx2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a);
+ }
+ }
+ for (; i > 1; i--) {
+ u64 unit = (1ull << i); /// u = 4
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_64_u4((__m256i*)(poly + j * unit), diff_j << 1, extra_a);
+ }
+ }
+ for (; i > 0; i--) {
+ u64 unit = (1ull << i); /// u = 2
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = butterfly_64_u2((__m128i*)(poly + j * unit), diff_j << 1, extra_a);
+ }
+ }
+ }
+
+ void i_btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a)
+ {
+ if (1 >= n_fx) return;
+
+ u64 log_n = __builtin_ctzll(n_fx);
+ u64 n_terms = n_fx;
+
+ uint64_t* poly = fx;
+ u64 i = 1;
+ for (; i < 2; i++) {
+ u64 unit = (1ull << i); /// u = 2
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_64_u2((__m128i*)(poly + j * unit), diff_j << 1, extra_a);
+ }
+ }
+ for (; i < 3; i++) {
+ u64 unit = (1ull << i); /// u = 4
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_64_u4((__m256i*)(poly + j * unit), diff_j << 1, extra_a);
+ }
+ }
+ for (; i < 4; i++) {
+ u64 unit = (1ull << i); /// u >= 8
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_64_avx2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a);
+ }
+ }
+ for (; i < 5; i++) {
+ u64 unit = (1ull << i); /// u >= 8
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_64_avx2_b2((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a);
+ }
+ }
+ for (; i <= log_n; i++) {
+ u64 unit = (1ull << i); /// u >= 8
+ u64 num = n_terms / unit;
+
+ u64 k = i - 1;
+ __m128i extra_a = (scalar_a > k) ? gf264_isomorphism_single_bit(scalar_a - k - 1) : _mm_setzero_si128();
+
+ u64 last_j = 0;
+ for (u64 j = 0; j < num; j++) {
+ u64 diff_j = j ^ last_j;
+ last_j = j;
+ extra_a = i_butterfly_64_avx2_b4((__m256i*)(poly + j * unit), unit >> 2, diff_j << 1, extra_a);
+ }
+ }
+ }
+}
diff --git a/butterfly_net.h b/bitpolymul/btfy.h
similarity index 72%
rename from butterfly_net.h
rename to bitpolymul/btfy.h
index 70a28c7..6951579 100644
--- a/butterfly_net.h
+++ b/bitpolymul/btfy.h
@@ -1,3 +1,4 @@
+#pragma once
/*
Copyright (C) 2017 Ming-Shing Chen
@@ -17,28 +18,21 @@ You should have received a copy of the GNU Lesser General Public License
along with BitPolyMul. If not, see .
*/
-#ifndef _BUTTERFLY_NET_H_
-#define _BUTTERFLY_NET_H_
-
-
#include
+#include "bpmDefines.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
+namespace bpm {
+ void btfy_128(uint64_t* fx, u64 n_fx, u64 scalar_a);
-void butterfly_net_half_inp_clmul( uint64_t * fx , unsigned n_fx );
+ void i_btfy_128(uint64_t* fx, u64 n_fx, u64 scalar_a);
-void i_butterfly_net_clmul( uint64_t * fx , unsigned n_fx );
+ void btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a);
-
-#ifdef __cplusplus
+ void i_btfy_64(uint64_t* fx, u64 n_fx, u64 scalar_a);
}
-#endif
-#endif
+
diff --git a/bitpolymul/encode.cpp b/bitpolymul/encode.cpp
new file mode 100644
index 0000000..8dabfd9
--- /dev/null
+++ b/bitpolymul/encode.cpp
@@ -0,0 +1,353 @@
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+
+#include
+
+#include "gfext_aesni.h"
+
+#include "bitmat_prod.h"
+
+#include "string.h"
+
+
+
+#include
+#include
+
+/////////////////////////////////////////////////
+///
+/// truncated FFT, 7 layers
+///
+//////////////////////////////////////////////////////
+
+#include "trunc_btfy_tab.h"
+#include "trunc_btfy_tab_64.h"
+
+#include "transpose.h"
+
+namespace bpm {
+
+ //USED;
+ inline
+ void bit_bc_64x2_div(__m256i* x)
+ {
+ for (u64 i = 0; i < 64; i++) x[64 + i] = _mm256_srli_si256(x[i], 8);
+ for (int i = 64 - 1; i >= 0; i--) {
+ x[1 + i] = xor256(x[1 + i], x[64 + i]);
+ x[4 + i] = xor256(x[4 + i], x[64 + i]);
+ x[16 + i] = xor256(x[16 + i], x[64 + i]);
+ }
+ for (u64 i = 0; i < 64; i++) x[i] = _mm256_unpacklo_epi64(x[i], x[64 + i]);
+
+ for (u64 i = 0; i < 64; i += 64) {
+ __m256i* pi = x + i;
+ for (int j = 32 - 1; j >= 0; j--) {
+ pi[1 + j] = xor256(pi[1 + j], pi[32 + j]);
+ pi[2 + j] = xor256(pi[2 + j], pi[32 + j]);
+ pi[16 + j] = xor256(pi[16 + j], pi[32 + j]);
+ }
+ }
+ for (u64 i = 0; i < 64; i += 32) {
+ __m256i* pi = x + i;
+ for (int j = 16 - 1; j >= 0; j--) {
+ pi[1 + j] = xor256(pi[1 + j], pi[16 + j]);
+ }
+ }
+ for (u64 i = 0; i < 64; i += 16) {
+ __m256i* pi = x + i;
+ for (int j = 8 - 1; j >= 0; j--) {
+ pi[1 + j] = xor256(pi[1 + j], pi[8 + j]);
+ pi[2 + j] = xor256(pi[2 + j], pi[8 + j]);
+ pi[4 + j] = xor256(pi[4 + j], pi[8 + j]);
+ }
+ }
+ for (u64 i = 0; i < 64; i += 8) {
+ __m256i* pi = x + i;
+ pi[4] = xor256(pi[4], pi[7]);
+ pi[3] = xor256(pi[3], pi[6]);
+ pi[2] = xor256(pi[2], pi[5]);
+ pi[1] = xor256(pi[1], pi[4]);
+ }
+
+ for (u64 i = 0; i < 64; i += 4) {
+ __m256i* pi = x + i;
+ pi[2] = xor256(pi[2], pi[3]);
+ pi[1] = xor256(pi[1], pi[2]);
+ }
+
+ }
+
+
+
+ //USED;
+ void encode_128_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b)
+ {
+ if (128 * 2 > n_fx_128b) { printf("unsupported number of terms.\n"); exit(-1); }
+
+ __m256i temp[128];
+ __m128i* temp128 = (__m128i*) temp;
+ uint64_t* temp64 = (uint64_t*)temp;
+ const __m256i* fx_256 = (const __m256i*) fx;
+ __m128i* rfx_128 = (__m128i*) rfx;
+ u64 n_fx_256b = n_fx_128b / 2;
+ u64 num = n_fx_256b / 128;
+ __m256i t2[128];
+ __m128i* t2_128 = (__m128i*) t2;
+
+ for (u64 i = 0; i < num; i++) {
+ for (u64 j = 0; j < 64; j++) {
+ temp[j] = fx_256[i + j * num];
+ temp[j] = div_s7(temp[j]);
+ }
+
+ tr_bit_64x64_b4_avx2((uint8_t*)(temp128), (const uint8_t*)temp);
+ bit_bc_64x2_div(temp);
+ // truncated FFT
+ for (u64 j = 0; j < 8; j++) {
+ bitmatrix_prod_64x128_4R_b32_opt_avx2((uint8_t*)(&t2_128[32 * j]), beta_mul_64_bm4r_ext_8, (const uint8_t*)(&temp64[32 * j]));
+ }
+ for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + k * 8 + j] = t2_128[k * 32 + j * 2];
+ for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + 64 + k * 8 + j] = t2_128[k * 32 + 16 + j * 2];
+ for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + 128 + k * 8 + j] = t2_128[k * 32 + j * 2 + 1];
+ for (u64 k = 0; k < 8; k++) for (u64 j = 0; j < 8; j++) rfx_128[i * 256 + 128 + 64 + k * 8 + j] = t2_128[k * 32 + 16 + j * 2 + 1];
+ }
+ }
+
+ //USED;
+ inline
+ void bit_bc_exp(__m256i* x)
+ {
+ for (u64 i = 0; i < 128; i += 4) {
+ __m256i* pi = x + i;
+ pi[1] = xor256(pi[1], pi[2]);
+ pi[2] = xor256(pi[2], pi[3]);
+ }
+ for (u64 i = 0; i < 128; i += 8) {
+ __m256i* pi = x + i;
+ pi[1] = xor256(pi[1], pi[4]);
+ pi[2] = xor256(pi[2], pi[5]);
+ pi[3] = xor256(pi[3], pi[6]);
+ pi[4] = xor256(pi[4], pi[7]);
+ }
+ for (u64 i = 0; i < 128; i += 16) {
+ __m256i* pi = x + i;
+ for (u64 j = 0; j < 8; j++) {
+ pi[1 + j] = xor256(pi[1 + j], pi[8 + j]);
+ pi[2 + j] = xor256(pi[2 + j], pi[8 + j]);
+ pi[4 + j] = xor256(pi[4 + j], pi[8 + j]);
+ }
+ }
+ for (u64 i = 0; i < 128; i += 32) {
+ __m256i* pi = x + i;
+ for (u64 j = 0; j < 16; j++) {
+ pi[1 + j] = xor256(pi[1 + j], pi[16 + j]);
+ }
+ }
+ for (u64 i = 0; i < 128; i += 64) {
+ __m256i* pi = x + i;
+ for (u64 j = 0; j < 32; j++) {
+ pi[1 + j] = xor256(pi[1 + j], pi[32 + j]);
+ pi[2 + j] = xor256(pi[2 + j], pi[32 + j]);
+ pi[16 + j] = xor256(pi[16 + j], pi[32 + j]);
+ }
+ }
+ for (u64 i = 0; i < 64; i++) {
+ x[1 + i] = xor256(x[1 + i], x[64 + i]);
+ x[4 + i] = xor256(x[4 + i], x[64 + i]);
+ x[16 + i] = xor256(x[16 + i], x[64 + i]);
+ }
+ }
+
+
+ void decode_128(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b)
+ {
+ if (128 * 2 > n_fx_128b) {
+ printf("unsupported number of terms.\n");
+ std::terminate();
+ }
+
+ const __m128i* fx_128 = (__m128i*) fx;
+ __m256i* rfx_256 = (__m256i*) rfx;
+ if (uint64_t(rfx_256) % 32)
+ {
+ printf("Error (Bitpolymul) pointer need to be 32 bit aligned. \n");
+ std::terminate();
+ }
+
+ u64 n_fx_256b = n_fx_128b / 2;
+ u64 num = n_fx_256b / 128;
+ __m256i temp[128];
+ __m128i* temp128 = (__m128i*) temp;
+
+ for (u64 i = 0; i < num; i++) {
+ /// truncated iFFT here.
+ for (u64 j = 0; j < 128; j++) {
+ temp128[j * 2] = fx_128[i * 256 + j];
+ temp128[j * 2 + 1] = fx_128[i * 256 + 128 + j];
+ }
+
+ for (u64 j = 0; j < 8; j++) {
+ bitmatrix_prod_128x128_4R_b32_opt_avx2((uint8_t*)(temp + 16 * j), i_beta_mul_64_bm4r_ext_8, (const uint8_t*)(temp + 16 * j));
+ }
+
+ bit_bc_exp(temp);
+
+ tr_bit_128x128_b2_avx2((uint8_t*)temp, (const uint8_t*)temp128);
+
+ for (u64 j = 0; j < 128; j++) {
+ temp[j] = exp_s7(temp[j]);
+ rfx_256[i + j * num] = temp[j];
+ }
+ }
+ }
+
+//
+//
+// ///////////////////////////////////////
+//
+//
+
+
+ inline
+ void bit_bc_64x2_exp(__m256i* x)
+ {
+ for (u64 i = 0; i < 64; i += 4) {
+ __m256i* pi = x + i;
+ pi[1] = xor256(pi[1], pi[2]);
+ pi[2] = xor256(pi[2], pi[3]);
+ }
+ for (u64 i = 0; i < 64; i += 8) {
+ __m256i* pi = x + i;
+ pi[1] = xor256(pi[1], pi[4]);
+ pi[2] = xor256(pi[2], pi[5]);
+ pi[3] = xor256(pi[3], pi[6]);
+ pi[4] = xor256(pi[4], pi[7]);
+ }
+ for (u64 i = 0; i < 64; i += 16) {
+ __m256i* pi = x + i;
+ for (u64 j = 0; j < 8; j++) {
+ pi[1 + j] = xor256(pi[1 + j], pi[8 + j]);
+ pi[2 + j] = xor256(pi[2 + j], pi[8 + j]);
+ pi[4 + j] = xor256(pi[4 + j], pi[8 + j]);
+ }
+ }
+ for (u64 i = 0; i < 64; i += 32) {
+ __m256i* pi = x + i;
+ for (u64 j = 0; j < 16; j++) {
+ pi[1 + j] = xor256(pi[1 + j], pi[16 + j]);
+ }
+ }
+ for (u64 i = 0; i < 64; i += 64) {
+ __m256i* pi = x + i;
+ for (u64 j = 0; j < 32; j++) {
+ pi[1 + j] = xor256(pi[1 + j], pi[32 + j]);
+ pi[2 + j] = xor256(pi[2 + j], pi[32 + j]);
+ pi[16 + j] = xor256(pi[16 + j], pi[32 + j]);
+ }
+ }
+
+ for (u64 i = 0; i < 64; i++) x[64 + i] = _mm256_srli_si256(x[i], 8);
+ for (u64 i = 0; i < 64; i++) {
+ x[1 + i] = xor256(x[1 + i], x[64 + i]);
+ x[4 + i] = xor256(x[4 + i], x[64 + i]);
+ x[16 + i] = xor256(x[16 + i], x[64 + i]);
+ }
+ for (u64 i = 0; i < 64; i++) x[i] = _mm256_unpacklo_epi64(x[i], x[64 + i]);
+
+ }
+
+
+
+
+
+
+ void encode_64_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx) /// XXX: further optimization.
+ {
+ if (64 * 4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); }
+
+ __m256i temp[128];
+ uint64_t* temp64 = (uint64_t*)temp;
+ const __m256i* fx_256 = (const __m256i*) fx;
+ u64 n_fx_256b = n_fx >> 2;
+ u64 num = n_fx_256b / 64;
+
+ for (u64 i = 0; i < num; i++) {
+ for (u64 j = 0; j < 32; j++) {
+ temp[j] = fx_256[i + j * num];
+ temp[j] = div_s7(temp[j]);
+ }
+ for (u64 j = 32; j < 64; j++) temp[j] = _mm256_setzero_si256();
+
+ tr_bit_64x64_b4_avx2((uint8_t*)(temp), (const uint8_t*)temp);
+
+ bit_bc_64x2_div(temp);
+
+ // truncated FFT
+ //for(u64 j=0;j<256;j++) temp64[j] = bitmatrix_prod_64x64_M4R( beta_mul_32_m4r , temp64[j] );
+#if 0
+ for (u64 j = 0; j < (64 * 4 / 32); j++) bitmatrix_prod_64x64_h32zero_4R_b32_avx2((uint8_t*)(&temp64[32 * j]), beta_mul_32_bm4r, (uint8_t*)(&temp64[32 * j]));
+#else
+ for (u64 j = 0; j < (64 * 4 / 64); j++) bitmatrix_prod_64x64_h32zero_4R_b64_avx2((uint8_t*)(&temp64[64 * j]), beta_mul_32_bm4r, (uint8_t*)(&temp64[64 * j]));
+#endif
+
+ for (u64 j = 0; j < 64; j++) rfx[i * 256 + j] = temp64[j * 4];
+ for (u64 j = 0; j < 64; j++) rfx[i * 256 + 64 + j] = temp64[j * 4 + 1];
+ for (u64 j = 0; j < 64; j++) rfx[i * 256 + 128 + j] = temp64[j * 4 + 2];
+ for (u64 j = 0; j < 64; j++) rfx[i * 256 + 192 + j] = temp64[j * 4 + 3];
+
+ }
+ }
+
+
+ void decode_64(uint64_t* rfx, const uint64_t* fx, u64 n_fx)
+ {
+ if (64 * 4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); }
+
+ __m256i temp[128];
+ uint64_t* temp64 = (uint64_t*)temp;
+
+ __m256i* rfx_256 = (__m256i*) rfx;
+ u64 n_fx_256b = n_fx >> 2;
+ u64 num = n_fx_256b / 64;
+
+ for (u64 i = 0; i < num; i++) {
+ /// truncated iFFT here.
+ for (u64 j = 0; j < 64; j++) {
+ temp64[j * 4] = fx[i * 256 + j];
+ temp64[j * 4 + 1] = fx[i * 256 + 64 + j];
+ temp64[j * 4 + 2] = fx[i * 256 + 128 + j];
+ temp64[j * 4 + 3] = fx[i * 256 + 192 + j];
+ }
+ // truncated iFFT
+ for (u64 j = 0; j < (64 * 4 / 64); j++) bitmatrix_prod_64x64_4R_b64_avx2((uint8_t*)(&temp64[64 * j]), i_beta_mul_32_bm4r, (uint8_t*)(&temp64[64 * j]));
+ bit_bc_64x2_exp(temp);
+
+ tr_bit_64x64_b4_avx2((uint8_t*)(temp), (const uint8_t*)temp);
+
+ for (u64 j = 0; j < 64; j++) {
+ temp[j] = exp_s7(temp[j]);
+
+ _mm256_store_si256(&rfx_256[i + j * num], temp[j]);
+ }
+ }
+ }
+}
+
diff --git a/gf2128_cantor_iso.h b/bitpolymul/encode.h
similarity index 67%
rename from gf2128_cantor_iso.h
rename to bitpolymul/encode.h
index 089cfef..37f0efb 100644
--- a/gf2128_cantor_iso.h
+++ b/bitpolymul/encode.h
@@ -1,3 +1,4 @@
+#pragma once
/*
Copyright (C) 2017 Ming-Shing Chen
@@ -17,33 +18,26 @@ You should have received a copy of the GNU Lesser General Public License
along with BitPolyMul. If not, see .
*/
-#ifndef _GF2128_CANTOR_ISO_H_
-#define _GF2128_CANTOR_ISO_H_
-#include
+#include
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "bpmDefines.h"
-extern uint64_t gf2128toCantor[];
+namespace bpm {
-extern uint64_t gfCantorto2128[];
-extern uint64_t gf2128toCantor_4R[];
+ void encode_128_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b);
-extern uint64_t gfCantorto2128_4R[];
+ void decode_128(uint64_t* rfx, const uint64_t* fx, u64 n_fx_128b);
+ void encode_64_half_input_zero(uint64_t* rfx, const uint64_t* fx, u64 n_fx);
-extern uint64_t gfCantorto2128_8R[];
+ void decode_64(uint64_t* rfx, const uint64_t* fx, u64 n_fx);
-#ifdef __cplusplus
}
-#endif
-#endif
diff --git a/gf2128_cantor_iso.c b/bitpolymul/gf2128_cantor_iso.h
similarity index 77%
rename from gf2128_cantor_iso.c
rename to bitpolymul/gf2128_cantor_iso.h
index e92dde9..89e0521 100644
--- a/gf2128_cantor_iso.c
+++ b/bitpolymul/gf2128_cantor_iso.h
@@ -18,9 +18,9 @@ along with BitPolyMul. If not, see .
*/
#include "stdint.h"
-
-
-uint64_t gf2128toCantor[2*128] __attribute__((aligned(32))) = {
+#include "bpmDefines.h"
+namespace bpm{
+alignas(32) const uint64_t gf2128toCantor[2*128] = {
0x1, 0x0,
0xF62DA500563A6180, 0x4E8FB76FADDE40EA,
0x8D3B77807D275140, 0x69C86CD87B31609F,
@@ -152,7 +152,7 @@ uint64_t gf2128toCantor[2*128] __attribute__((aligned(32))) = {
};
-uint64_t gfCantorto2128[2*128] __attribute__((aligned(32))) = {
+alignas(32) const uint64_t gfCantorto2128[2*128] = {
0x1, 0x0,
0x676AAC9FA4B20B08, 0x295AC0B1F4731AF9,
0xFF1099C31BBE8F22, 0xA2134422CD4054C9,
@@ -284,7 +284,7 @@ uint64_t gfCantorto2128[2*128] __attribute__((aligned(32))) = {
};
-uint64_t gf2128toCantor_4R[2*(16*2*16)] __attribute__((aligned(32))) = {
+alignas(32) const uint64_t gf2128toCantor_4R[2*(16*2*16)] = {
0x0,0x0,
0x1,0x0,
@@ -799,526 +799,526 @@ uint64_t gf2128toCantor_4R[2*(16*2*16)] __attribute__((aligned(32))) = {
0x98a7248cd4418a12,0xeb64d569d4cb325e,
0x918ec244d33ea76e,0xd6b8e78ee77513c6,
};
-
-uint64_t gfCantorto2128_4R[2*(16*2*16)] __attribute__((aligned(32))) = {
-0x0,0x0,
-0x1,0x0,
-0x676aac9fa4b20b08,0x295ac0b1f4731af9,
-0x676aac9fa4b20b09,0x295ac0b1f4731af9,
-0xff1099c31bbe8f22,0xa2134422cd4054c9,
-0xff1099c31bbe8f23,0xa2134422cd4054c9,
-0x987a355cbf0c842a,0x8b49849339334e30,
-0x987a355cbf0c842b,0x8b49849339334e30,
-0x53b85b6402b1e848,0x7959d70ce1ee6942,
-0x53b85b6402b1e849,0x7959d70ce1ee6942,
-0x34d2f7fba603e340,0x500317bd159d73bb,
-0x34d2f7fba603e341,0x500317bd159d73bb,
-0xaca8c2a7190f676a,0xdb4a932e2cae3d8b,
-0xaca8c2a7190f676b,0xdb4a932e2cae3d8b,
-0xcbc26e38bdbd6c62,0xf210539fd8dd2772,
-0xcbc26e38bdbd6c63,0xf210539fd8dd2772,
-0x0,0x0,
-0xcabcd8e4694e5644,0x8f6b313e935b8e2,
-0x4d48b16661e860ec,0x49c9321635282198,
-0x87f4698208a636a8,0x413f8105dc1d997a,
-0xa13fe8ac5560ce0c,0x53d8555a9979a1c,
-0x6b8330483c2e9848,0xdcb364640a222fe,
-0xec7759ca3488aee0,0x4cf4b7439cbfbb84,
-0x26cb812e5dc6f8a4,0x44020450758a0366,
-0x5cb10fbabcf00118,0x4d52354a3a3d8c86,
-0x960dd75ed5be575c,0x45a48659d3083464,
-0x11f9bedcdd1861f4,0x49b075c0f15ad1e,
-0xdb456638b45637b0,0xc6db44fe62015fc,
-0xfd8ee716e990cf14,0x486fb01f93aa169a,
-0x37323ff280de9950,0x4099030c7a9fae78,
-0xb0c656708878aff8,0x1a68209a6823702,
-0x7a7a8e94e136f9bc,0x950311a4fb78fe0,
-0x0,0x0,
-0xe18c55b8e07d3612,0x2ccae6ed8d6b4cd0,
-0x588b6244c5d74470,0x210d8fbe72672c66,
-0xb90737fc25aa7262,0xdc76953ff0c60b6,
-0xd047dada84654da4,0xc211182c85e148b3,
-0x31cb8f6264187bb6,0xeedbfec1088a0463,
-0x88ccb89e41b209d4,0xe31c9792f78664d5,
-0x6940ed26a1cf3fc6,0xcfd6717f7aed2805,
-0xfed3b473eeb39df8,0x104d101e47f1f112,
-0x1f5fe1cb0eceabea,0x3c87f6f3ca9abdc2,
-0xa658d6372b64d988,0x31409fa03596dd74,
-0x47d4838fcb19ef9a,0x1d8a794db8fd91a4,
-0x2e946ea96ad6d05c,0xd25c0832c210b9a1,
-0xcf183b118aabe64e,0xfe96eedf4f7bf571,
-0x761f0cedaf01942c,0xf351878cb07795c7,
-0x979359554f7ca23e,0xdf9b61613d1cd917,
-0x0,0x0,
-0xbf199eb4f675f2ac,0xce955ea0da2a682b,
-0x19c55b8d6bef4c98,0xdbacfb2ac336178f,
-0xa6dcc5399d9abe34,0x1539a58a191c7fa4,
-0xf5531b28858156d0,0x58770bc4e101ab94,
-0x4a4a859c73f4a47c,0x96e255643b2bc3bf,
-0xec9640a5ee6e1a48,0x83dbf0ee2237bc1b,
-0x538fde11181be8e4,0x4d4eae4ef81dd430,
-0x8b97b65b221cc4e4,0x497f8adb47e0ae82,
-0x348e28efd4693648,0x87ead47b9dcac6a9,
-0x9252edd649f3887c,0x92d371f184d6b90d,
-0x2d4b7362bf867ad0,0x5c462f515efcd126,
-0x7ec4ad73a79d9234,0x1108811fa6e10516,
-0xc1dd33c751e86098,0xdf9ddfbf7ccb6d3d,
-0x6701f6fecc72deac,0xcaa47a3565d71299,
-0xd818684a3a072c00,0x4312495bffd7ab2,
-0x0,0x0,
-0xa10cfc6a1654c578,0x5aa755df14f64da,
-0xbae99a4e3fbe0c54,0x82db354523f40c7b,
-0x1be5662429eac92c,0x87714018d2bb68a1,
-0x8e808ec2a80c4662,0xba5ba13dbf25ee6b,
-0x2f8c72a8be58831a,0xbff1d4604e6a8ab1,
-0x3469148c97b24a36,0x388094789cd1e210,
-0x9565e8e681e68f4e,0x3d2ae1256d9e86ca,
-0x5c2b82c39ef7a93c,0x300b8602354dbc70,
-0xfd277ea988a36c44,0x35a1f35fc402d8aa,
-0xe6c2188da149a568,0xb2d0b34716b9b00b,
-0x47cee4e7b71d6010,0xb77ac61ae7f6d4d1,
-0xd2ab0c0136fbef5e,0x8a50273f8a68521b,
-0x73a7f06b20af2a26,0x8ffa52627b2736c1,
-0x6842964f0945e30a,0x88b127aa99c5e60,
-0xc94e6a251f112672,0xd21672758d33aba,
-0x0,0x0,
-0x882e2943d5ee4534,0xc25f5e75edaa4fa9,
-0x95d3204b1d1dd922,0x39092e35de04cc32,
-0x1dfd0908c8f39c16,0xfb56704033ae839b,
-0xcb6e1a7035541fd6,0x8ab363f0b1f0f211,
-0x43403333e0ba5ae2,0x48ec3d855c5abdb8,
-0x5ebd3a3b2849c6f4,0xb3ba4dc56ff43e23,
-0xd6931378fda783c0,0x71e513b0825e718a,
-0xa1318678293664f4,0xbe1eca746232042b,
-0x291faf3bfcd821c0,0x7c4194018f984b82,
-0x34e2a633342bbdd6,0x8717e441bc36c819,
-0xbccc8f70e1c5f8e2,0x4548ba34519c87b0,
-0x6a5f9c081c627b22,0x34ada984d3c2f63a,
-0xe271b54bc98c3e16,0xf6f2f7f13e68b993,
-0xff8cbc43017fa200,0xda487b10dc63a08,
-0x77a29500d491e734,0xcffbd9c4e06c75a1,
-0x0,0x0,
-0xe684ecc9b397a5fe,0xb3b2d35103f1a3ed,
-0x6da6f30e41a8edf0,0x34b0cc6ccf4ee620,
-0x8b221fc7f23f480e,0x87021f3dccbf45cd,
-0xacd605531d728f16,0xa6af6a59808b2143,
-0x4a52e99aaee52ae8,0x151db908837a82ae,
-0xc170f65d5cda62e6,0x921fa6354fc5c763,
-0x27f41a94ef4dc718,0x21ad75644c34648e,
-0x36771e3ca90ca14,0x3555819a552c1192,
-0xe5e39d2a79076fea,0x86e752cb56ddb27f,
-0x6ec182ed8b3827e4,0x1e54df69a62f7b2,
-0x88456e2438af821a,0xb2579ea79993545f,
-0xafb174b0d7e24502,0x93faebc3d5a730d1,
-0x493598796475e0fc,0x20483892d656933c,
-0xc21787be964aa8f2,0xa74a27af1ae9d6f1,
-0x24936b7725dd0d0c,0x14f8f4fe1918751c,
-0x0,0x0,
-0xc6c1932eeb78b72a,0xeabea114c8ae9a9f,
-0xfc5874dd3b9425ce,0x1988519c2a18a57c,
-0x3a99e7f3d0ec92e4,0xf336f088e2b63fe3,
-0x70ec558472062c44,0x60abfabc33f697de,
-0xb62dc6aa997e9b6e,0x8a155ba8fb580d41,
-0x8cb421594992098a,0x7923ab2019ee32a2,
-0x4a75b277a2eabea0,0x939d0a34d140a83d,
-0xa9e47128863ba654,0xdf68fe1cdf73f30,
-0x6f25e2066d43117e,0xe7482ef50559a5af,
-0x55bc05f5bdaf839a,0x147ede7de7ef9a4c,
-0x937d96db56d734b0,0xfec07f692f4100d3,
-0xd90824acf43d8a10,0x6d5d755dfe01a8ee,
-0x1fc9b7821f453d3a,0x87e3d44936af3271,
-0x25505071cfa9afde,0x74d524c1d4190d92,
-0xe391c35f24d118f4,0x9e6b85d51cb7970d,
-0x0,0x0,
-0x8b6f419ea9e92f64,0x87506cbe98650ee9,
-0xae03a86096676122,0xbb5791719ba8f14f,
-0x256ce9fe3f8e4e46,0x3c07fdcf03cdffa6,
-0xba49ef0905bed85a,0x9ae42542db02833b,
-0x3126ae97ac57f73e,0x1db449fc43678dd2,
-0x144a476993d9b978,0x21b3b43340aa7274,
-0x9f2506f73a30961c,0xa6e3d88dd8cf7c9d,
-0x997880bebf7eb61c,0xf29856ca664755b9,
-0x1217c12016979978,0x75c83a74fe225b50,
-0x377b28de2919d73e,0x49cfc7bbfdefa4f6,
-0xbc14694080f0f85a,0xce9fab05658aaa1f,
-0x23316fb7bac06e46,0x687c7388bd45d682,
-0xa85e2e2913294122,0xef2c1f362520d86b,
-0x8d32c7d72ca70f64,0xd32be2f926ed27cd,
-0x65d8649854e2000,0x547b8e47be882924,
-0x0,0x0,
-0x16cb3187d20086c,0x9e37d35816d18239,
-0x248c663b21703abe,0x71815387f77f4dbc,
-0x25e0d5235c5032d2,0xefb680dfe1aecf85,
-0x143024f5848f1090,0xa6d469fdbe031ab9,
-0x155c97edf9af18fc,0x38e3baa5a8d29880,
-0x30bc42cea5ff2a2e,0xd7553a7a497c5705,
-0x31d0f1d6d8df2242,0x4962e9225fadd53c,
-0x790935af79870be0,0x1d83ab0444495694,
-0x786586b704a7038c,0x83b4785c5298d4ad,
-0x5d85539458f7315e,0x6c02f883b3361b28,
-0x5ce9e08c25d73932,0xf2352bdba5e79911,
-0x6d39115afd081b70,0xbb57c2f9fa4a4c2d,
-0x6c55a2428028131c,0x256011a1ec9bce14,
-0x49b57761dc7821ce,0xcad6917e0d350191,
-0x48d9c479a15829a2,0x54e142261be483a8,
-0x0,0x0,
-0xbe2444c534740484,0xcbaf5837829b974f,
-0x5efc7f3aa24d39ca,0xf36a42b3e5f1cbbb,
-0xe0d83bff96393d4e,0x38c51a84676a5cf4,
-0x92372db327a9d5ee,0x1cf5645b85d85ac4,
-0x2c13697613ddd16a,0xd75a3c6c0743cd8b,
-0xcccb528985e4ec24,0xef9f26e86029917f,
-0x72ef164cb190e8a0,0x24307edfe2b20630,
-0xd48cd14917a38034,0xe374c7526e3abf93,
-0x6aa8958c23d784b0,0x28db9f65eca128dc,
-0x8a70ae73b5eeb9fe,0x101e85e18bcb7428,
-0x3454eab6819abd7a,0xdbb1ddd60950e367,
-0x46bbfcfa300a55da,0xff81a309ebe2e557,
-0xf89fb83f047e515e,0x342efb3e69797218,
-0x184783c092476c10,0xcebe1ba0e132eec,
-0xa663c705a6336894,0xc744b98d8c88b9a3,
-0x0,0x0,
-0x2490765a301e28c2,0xb608a7b1ade6f573,
-0xaa56dfd514863cf6,0x9ec927e0ea730849,
-0x8ec6a98f24981434,0x28c180514795fd3a,
-0xb493920663b35d20,0xf2eee16207fa6641,
-0x9003e45c53ad75e2,0x44e646d3aa1c9332,
-0x1ec54dd3773561d6,0x6c27c682ed896e08,
-0x3a553b89472b4914,0xda2f6133406f9b7b,
-0x9b78c9542bba3a2e,0x79c54cdd0e226966,
-0xbfe8bf0e1ba412ec,0xcfcdeb6ca3c49c15,
-0x312e16813f3c06d8,0xe70c6b3de451612f,
-0x15be60db0f222e1a,0x5104cc8c49b7945c,
-0x2feb5b524809670e,0x8b2badbf09d80f27,
-0xb7b2d0878174fcc,0x3d230a0ea43efa54,
-0x85bd84875c8f5bf8,0x15e28a5fe3ab076e,
-0xa12df2dd6c91733a,0xa3ea2dee4e4df21d,
-0x0,0x0,
-0x456895c1d95fe234,0xee72b1a21497e77b,
-0x4eb77b48cc5f7038,0x9ad3c105b155ffef,
-0xbdfee891500920c,0x74a170a7a5c21894,
-0x68f65fa05931208c,0x585b4042d008c9da,
-0x2d9eca61806ec2b8,0xb629f1e0c49f2ea1,
-0x264124e8956e50b4,0xc2888147615d3635,
-0x6329b1294c31b280,0x2cfa30e575cad14e,
-0x16dde2bb2b38dcfa,0xaeca82ee463b0b3b,
-0x53b5777af2673ece,0x40b8334c52acec40,
-0x586a99f3e767acc2,0x341943ebf76ef4d4,
-0x1d020c323e384ef6,0xda6bf249e3f913af,
-0x7e2bbd1b7209fc76,0xf691c2ac9633c2e1,
-0x3b4328daab561e42,0x18e3730e82a4259a,
-0x309cc653be568c4e,0x6c4203a927663d0e,
-0x75f4539267096e7a,0x8230b20b33f1da75,
-0x0,0x0,
-0x3904c8d2f5c3d2d6,0x54d2b7c147b9eab0,
-0x8b1c8bd76f237756,0x4d81761ce690153e,
-0xb21843059ae0a580,0x1953c1dda129ff8e,
-0x8a2133f2160fc5ec,0x614a21c3ff3bf28a,
-0xb325fb20e3cc173a,0x35989602b882183a,
-0x13db825792cb2ba,0x2ccb57df19abe7b4,
-0x383970f78cef606c,0x7819e01e5e120d04,
-0x4b053b0413b7ed2a,0xa7cdb8c6809748d7,
-0x7201f3d6e6743ffc,0xf31f0f07c72ea267,
-0xc019b0d37c949a7c,0xea4cceda66075de9,
-0xf91d7801895748aa,0xbe9e791b21beb759,
-0xc12408f605b828c6,0xc68799057facba5d,
-0xf820c024f07bfa10,0x92552ec4381550ed,
-0x4a3883216a9b5f90,0x8b06ef19993caf63,
-0x733c4bf39f588d46,0xdfd458d8de8545d3,
-0x0,0x0,
-0x14e4307f9d1772b6,0x515219ca23f9ce5c,
-0x511e34506522e6ae,0x8247627f48ff1f7f,
-0x45fa042ff8359418,0xd3157bb56b06d123,
-0xe3a3756c6efacfc4,0xf788c793e7244e9f,
-0xf7474513f3edbd72,0xa6dade59c4dd80c3,
-0xb2bd413c0bd8296a,0x75cfa5ecafdb51e0,
-0xa659714396cf5bdc,0x249dbc268c229fbc,
-0x5a70839fc81fb4c0,0xd35f0eb88cae752b,
-0x4e94b3e05508c676,0x820d1772af57bb77,
-0xb6eb7cfad3d526e,0x51186cc7c4516a54,
-0x1f8a87b0302a20d8,0x4a750de7a8a408,
-0xb9d3f6f3a6e57b04,0x24d7c92b6b8a3bb4,
-0xad37c68c3bf209b2,0x7585d0e14873f5e8,
-0xe8cdc2a3c3c79daa,0xa690ab54237524cb,
-0xfc29f2dc5ed0ef1c,0xf7c2b29e008cea97,
-0x0,0x0,
-0xda8e23483a97853a,0x38f065e6ec77c32c,
-0xd1700ce51721220c,0xee558f30070e0c3d,
-0xbfe2fad2db6a736,0xd6a5ead6eb79cf11,
-0x249484a90e31ef88,0xd78f250953e96933,
-0xfe1aa7e134a66ab2,0xef7f40efbf9eaa1f,
-0xf5e4884c1910cd84,0x39daaa3954e7650e,
-0x2f6aab04238748be,0x12acfdfb890a622,
-0x771a1494d77054ac,0xde34b71e0312848f,
-0xad9437dcede7d196,0xe6c4d2f8ef6547a3,
-0xa66a1871c05176a0,0x3061382e041c88b2,
-0x7ce43b39fac6f39a,0x8915dc8e86b4b9e,
-0x538e903dd941bb24,0x9bb921750fbedbc,
-0x8900b375e3d63e1e,0x314bf7f1bc8c2e90,
-0x82fe9cd8ce609928,0xe7ee1d2757f5e181,
-0x5870bf90f4f71c12,0xdf1e78c1bb8222ad,
-0x0,0x0,
-0x27f349141093e620,0x97e14e9448decae7,
-0x8da828e52be94d70,0x928de3c8e22c0f1d,
-0xaa5b61f13b7aab50,0x56cad5caaf2c5fa,
-0xc1e9db8ac9f1c256,0xba586143dfe63deb,
-0xe61a929ed9622476,0x2db92fd79738f70c,
-0x4c41f36fe2188f26,0x28d5828b3dca32f6,
-0x6bb2ba7bf28b6906,0xbf34cc1f7514f811,
-0xd9b45813424b2b38,0xb2052ca6fb35eaa9,
-0xfe47110752d8cd18,0x25e46232b3eb204e,
-0x541c70f669a26648,0x2088cf6e1919e5b4,
-0x73ef39e279318068,0xb76981fa51c72f53,
-0x185d83998bbae96e,0x85d4de524d3d742,
-0x3faeca8d9b290f4e,0x9fbc03716c0d1da5,
-0x95f5ab7ca053a41e,0x9ad0ae2dc6ffd85f,
-0xb206e268b0c0423e,0xd31e0b98e2112b8,
-0x0,0x0,
-0x10f28ab6172a4efa,0x794a2a7c84a76d2c,
-0x213491af2f858c38,0xa3fb2735d34fbaa7,
-0x31c61b1938afc2c2,0xdab10d4957e8d78b,
-0xdd93cc151a20dcda,0xfa7ca4a3574c6525,
-0xcd6146a30d0a9220,0x83368edfd3eb0809,
-0xfca75dba35a550e2,0x598783968403df82,
-0xec55d70c228f1e18,0x20cda9ea00a4b2ae,
-0x3190a2225ab65e2c,0xff5e390da90f4835,
-0x216228944d9c10d6,0x861413712da82519,
-0x10a4338d7533d214,0x5ca51e387a40f292,
-0x56b93b62199cee,0x25ef3444fee79fbe,
-0xec036e37409682f6,0x5229daefe432d10,
-0xfcf1e48157bccc0c,0x7c68b7d27ae4403c,
-0xcd37ff986f130ece,0xa6d9ba9b2d0c97b7,
-0xddc5752e78394034,0xdf9390e7a9abfa9b,
-0x0,0x0,
-0x71389b2a8246f5e4,0xd79573b001f21771,
-0x6ae0532ae2bbfb90,0xdfd3122b95e92c4f,
-0x1bd8c80060fd0e74,0x846619b941b3b3e,
-0xcd6b22d4c21c7758,0x59ee81e35141d3cc,
-0xbc53b9fe405a82bc,0x8e7bf25350b3c4bd,
-0xa78b71fe20a78cc8,0x863d93c8c4a8ff83,
-0xd6b3ead4a2e1792c,0x51a8e078c55ae8f2,
-0x85e338536eb1bbc,0xca785a7f809253d7,
-0x7966a8afb4adee58,0x1ded29cf816044a6,
-0x62be60afd450e02c,0x15ab4854157b7f98,
-0x1386fb85561615c8,0xc23e3be4148968e9,
-0xc5351151f4f76ce4,0x9396db9cd1d3801b,
-0xb40d8a7b76b19900,0x4403a82cd021976a,
-0xafd5427b164c9774,0x4c45c9b7443aac54,
-0xdeedd951940a6290,0x9bd0ba0745c8bb25,
-0x0,0x0,
-0xa602f3fd08bbca2a,0x3cf77b9a1ded625a,
-0x9cfb59155f2c296a,0xc74456a7f1e3b58b,
-0x3af9aae85797e340,0xfbb32d3dec0ed7d1,
-0xbc92de7f7ebfd6c4,0x38ff17882d7d411c,
-0x1a902d8276041cee,0x4086c1230902346,
-0x2069876a2193ffae,0xffbb412fdc9ef497,
-0x866b749729283584,0xc34c3ab5c17396cd,
-0x49dd31700df81d26,0x6daab92652394278,
-0xefdfc28d0543d70c,0x515dc2bc4fd42022,
-0xd526686552d4344c,0xaaeeef81a3daf7f3,
-0x73249b985a6ffe66,0x9619941bbe3795a9,
-0xf54fef0f7347cbe2,0x5555aeae7f440364,
-0x534d1cf27bfc01c8,0x69a2d53462a9613e,
-0x69b4b61a2c6be288,0x9211f8098ea7b6ef,
-0xcfb645e724d028a2,0xaee68393934ad4b5,
-0x0,0x0,
-0x3b8f902c0a858e4e,0x8b95b6a7427690cb,
-0xd525a8185f8af324,0xf31f1e9daabbff9f,
-0xeeaa3834550f7d6a,0x788aa83ae8cd6f54,
-0x17f87f09bc736f26,0xfafd49e2ee8251e9,
-0x2c77ef25b6f6e168,0x7168ff45acf4c122,
-0xc2ddd711e3f99c02,0x9e2577f4439ae76,
-0xf952473de97c124c,0x8277e1d8064f3ebd,
-0xae5fb3551c95931e,0x1863362e3ae97756,
-0x95d0237916101d50,0x93f68089789fe79d,
-0x7b7a1b4d431f603a,0xeb7c28b3905288c9,
-0x40f58b61499aee74,0x60e99e14d2241802,
-0xb9a7cc5ca0e6fc38,0xe29e7fccd46b26bf,
-0x82285c70aa637276,0x690bc96b961db674,
-0x6c826444ff6c0f1c,0x118161517ed0d920,
-0x570df468f5e98152,0x9a14d7f63ca649eb,
-0x0,0x0,
-0x9b8f8f876479058e,0xcad343e8080cba83,
-0x51bbcc440c472768,0xf2e5a279864a60f5,
-0xca3443c3683e22e6,0x3836e1918e46da76,
-0x6340402c3f7ffebe,0xb70b9103d1cd6617,
-0xf8cfcfab5b06fb30,0x7dd8d2ebd9c1dc94,
-0x32fb8c683338d9d6,0x45ee337a578706e2,
-0xa97403ef5741dc58,0x8f3d70925f8bbc61,
-0xdeb9ef235f15ff90,0xb7959b94e1e22d49,
-0x453660a43b6cfa1e,0x7d46d87ce9ee97ca,
-0x8f0223675352d8f8,0x457039ed67a84dbc,
-0x148dace0372bdd76,0x8fa37a056fa4f73f,
-0xbdf9af0f606a012e,0x9e0a97302f4b5e,
-0x26762088041304a0,0xca4d497f3823f1dd,
-0xec42634b6c2d2646,0xf27ba8eeb6652bab,
-0x77cdeccc085423c8,0x38a8eb06be699128,
-0x0,0x0,
-0x5a9d3675a3531196,0x3524ce9c7f7b56e2,
-0xce10620e568164c2,0x8ef7ee5cecdb882d,
-0x948d547bf5d27554,0xbbd320c093a0decf,
-0x854d0fea22c345b2,0xda3844c594d764bf,
-0xdfd0399f81905424,0xef1c8a59ebac325d,
-0x4b5d6de474422170,0x54cfaa99780cec92,
-0x11c05b91d71130e6,0x61eb64050777ba70,
-0x16c016c2d631ae74,0xf2328df87cdf3e71,
-0x4c5d20b77562bfe2,0xc716436403a46893,
-0xd8d074cc80b0cab6,0x7cc563a49004b65c,
-0x824d42b923e3db20,0x49e1ad38ef7fe0be,
-0x938d1928f4f2ebc6,0x280ac93de8085ace,
-0xc9102f5d57a1fa50,0x1d2e07a197730c2c,
-0x5d9d7b26a2738f04,0xa6fd276104d3d2e3,
-0x7004d5301209e92,0x93d9e9fd7ba88401,
-0x0,0x0,
-0x3a9122c15f3ab78,0x9eb8b35a2448eeff,
-0x4ac1ab2d94aa463e,0x3c449b0a0456c972,
-0x4968b9018159ed46,0xa2fc2850201e278d,
-0x70d846ae38ffb938,0x6cddd4542b3a7254,
-0x737154822d0c1240,0xf265670e0f729cab,
-0x3a19ed83ac55ff06,0x50994f5e2f6cbb26,
-0x39b0ffafb9a6547e,0xce21fc040b2455d9,
-0x3f1ab33bdd022656,0xee26c355dcac88cf,
-0x3cb3a117c8f18d2e,0x709e700ff8e46630,
-0x75db181649a86068,0xd262585fd8fa41bd,
-0x76720a3a5c5bcb10,0x4cdaeb05fcb2af42,
-0x4fc2f595e5fd9f6e,0x82fb1701f796fa9b,
-0x4c6be7b9f00e3416,0x1c43a45bd3de1464,
-0x5035eb87157d950,0xbebf8c0bf3c033e9,
-0x6aa4c9464a47228,0x20073f51d788dd16,
-0x0,0x0,
-0xa2def1742f3b5916,0x55fe928ccc907446,
-0xc0536b0be526eb6,0xce0290a08ea7ed67,
-0xaedbc7c4916937a0,0x9bfc022c42379921,
-0x63118f8310afbd9c,0xf3bfe1a1625671ef,
-0xc1cf7ef73f94e48a,0xa641732daec605a9,
-0x6f14b933aefdd32a,0x3dbd7101ecf19c88,
-0xcdca484781c68a3c,0x6843e38d2061e8ce,
-0x5c5ad70dd7f32ae,0xfbdcaf23d12e7a5d,
-0xa71b5c04f2446bb8,0xae223daf1dbe0e1b,
-0x9c09bc0632d5c18,0x35de3f835f89973a,
-0xab1e6ab44c16050e,0x6020ad0f9319e37c,
-0x66d422f3cdd08f32,0x8634e82b3780bb2,
-0xc40ad387e2ebd624,0x5d9ddc0e7fe87ff4,
-0x6ad114437382e184,0xc661de223ddfe6d5,
-0xc80fe5375cb9b892,0x939f4caef14f9293,
-0x0,0x0,
-0x2cd73c266f68da36,0x9bfcfcadd6ed8b57,
-0x6d8e1fe42b061d44,0x3db9c6976df592a6,
-0x415923c2446ec772,0xa6453a3abb1819f1,
-0x80ca05549a4dc27c,0xc75a42071ff8895d,
-0xac1d3972f525184a,0x5ca6beaac915020a,
-0xed441ab0b14bdf38,0xfae38490720d1bfb,
-0xc1932696de23050e,0x611f783da4e090ac,
-0xd1fbff53b9e5b9a0,0x11f736abdbe2672a,
-0xfd2cc375d68d6396,0x8a0bca060d0fec7d,
-0xbc75e0b792e3a4e4,0x2c4ef03cb617f58c,
-0x90a2dc91fd8b7ed2,0xb7b20c9160fa7edb,
-0x5131fa0723a87bdc,0xd6ad74acc41aee77,
-0x7de6c6214cc0a1ea,0x4d51880112f76520,
-0x3cbfe5e308ae6698,0xeb14b23ba9ef7cd1,
-0x1068d9c567c6bcae,0x70e84e967f02f786,
-0x0,0x0,
-0xc1ca004429d1c70c,0x83670004dbe27f63,
-0x7ade7ba41da719e2,0x75ff5173392ad2ea,
-0xbb147be03476deee,0xf6985177e2c8ad89,
-0x2da0b1432202bae2,0xc33784b9b478b88b,
-0xec6ab1070bd37dee,0x405084bd6f9ac7e8,
-0x577ecae73fa5a300,0xb6c8d5ca8d526a61,
-0x96b4caa31674640c,0x35afd5ce56b01502,
-0x88cc8045cdff4040,0x39324dfdad64aa8e,
-0x49068001e42e874c,0xba554df97686d5ed,
-0xf212fbe1d05859a2,0x4ccd1c8e944e7864,
-0x33d8fba5f9899eae,0xcfaa1c8a4fac0707,
-0xa56c3106effdfaa2,0xfa05c944191c1205,
-0x64a63142c62c3dae,0x7962c940c2fe6d66,
-0xdfb24aa2f25ae340,0x8ffa98372036c0ef,
-0x1e784ae6db8b244c,0xc9d9833fbd4bf8c,
-0x0,0x0,
-0xd1537109b42cc8a0,0x8b6232e621520ca1,
-0xc5585ec70c29b8f0,0x961f8facdb0ea92d,
-0x140b2fceb8057050,0x1d7dbd4afa5ca58c,
-0x641e0bbe37274246,0x38e42a8ae4b60f8e,
-0xb54d7ab7830b8ae6,0xb386186cc5e4032f,
-0xa14655793b0efab6,0xaefba5263fb8a6a3,
-0x701524708f223216,0x259997c01eeaaa02,
-0xb1f69a8517d41456,0xc70e543a5a80f74b,
-0x60a5eb8ca3f8dcf6,0x4c6c66dc7bd2fbea,
-0x74aec4421bfdaca6,0x5111db96818e5e66,
-0xa5fdb54bafd16406,0xda73e970a0dc52c7,
-0xd5e8913b20f35610,0xffea7eb0be36f8c5,
-0x4bbe03294df9eb0,0x74884c569f64f464,
-0x10b0cffc2cdaeee0,0x69f5f11c653851e8,
-0xc1e3bef598f62640,0xe297c3fa446a5d49,
-0x0,0x0,
-0xbccf8ca839bfe3a8,0x38bd7652fbb4463c,
-0xc4fab69066e3433a,0xefa5f7ca9f6294c1,
-0x78353a385f5ca092,0xd718819864d6d2fd,
-0xb54afad4cd1155a8,0x31317c030896c74a,
-0x985767cf4aeb600,0x98c0a51f3228176,
-0x71b04c44abf21692,0xde948bc997f4538b,
-0xcd7fc0ec924df53a,0xe629fd9b6c4015b7,
-0x7d4bba2cbae355d4,0xd5fb04e16da98b6,
-0xc1843684835cb67c,0x35e2c61ced6ede8a,
-0xb9b10cbcdc0016ee,0xe2fa478489b80c77,
-0x57e8014e5bff546,0xda4731d6720c4a4b,
-0xc80140f877f2007c,0x3c6ecc4d1e4c5ffc,
-0x74cecc504e4de3d4,0x4d3ba1fe5f819c0,
-0xcfbf66811114346,0xd3cb3b87812ecb3d,
-0xb0347ac028aea0ee,0xeb764dd57a9a8d01,
-0x0,0x0,
-0xfd2b185552fcca1e,0xaf27a2c3c9af3b15,
-0xa74e3032c1c70940,0xb22c87060644347d,
-0x5a652867933bc35e,0x1d0b25c5cfeb0f68,
-0x96784c18fa9a222c,0x9f1317dd9bd62b2b,
-0x6b53544da866e832,0x3034b51e5279103e,
-0x31367c2a3b5d2b6c,0x2d3f90db9d921f56,
-0xcc1d647f69a1e172,0x82183218543d2443,
-0xa055412a1255732c,0x9675e5102f20a86d,
-0x5d7e597f40a9b932,0x395247d3e68f9378,
-0x71b7118d3927a6c,0x2459621629649c10,
-0xfa30694d816eb072,0x8b7ec0d5e0cba705,
-0x362d0d32e8cf5100,0x966f2cdb4f68346,
-0xcb061567ba339b1e,0xa641500e7d59b853,
-0x91633d0029085840,0xbb4a75cbb2b2b73b,
-0x6c4825557bf4925e,0x146dd7087b1d8c2e,
-0x0,0x0,
-0xbd9e54181b305f0,0x1196f9167176350a,
-0x2de9c7568ec18048,0x4c7d6f6a66426bc8,
-0x263022170f7285b8,0x5deb967c17345ec2,
-0xf69478d0555733be,0x2cf2076679e35cae,
-0xfd4d9d91d4e4364e,0x3d64fe70089569a4,
-0xdb7dbf86db96b3f6,0x608f680c1fa13766,
-0xd0a45ac75a25b606,0x7119911a6ed7026c,
-0xa0dea3eaee857928,0xeff27f24fdcf1cb1,
-0xab0746ab6f367cd8,0xfe6486328cb929bb,
-0x8d3764bc6044f960,0xa38f104e9b8d7779,
-0x86ee81fde1f7fc90,0xb219e958eafb4273,
-0x564adb3abbd24a96,0xc3007842842c401f,
-0x5d933e7b3a614f66,0xd2968154f55a7515,
-0x7ba31c6c3513cade,0x8f7d1728e26e2bd7,
-0x707af92db4a0cf2e,0x9eebee3e93181edd,
-0x0,0x0,
-0x22de535186312472,0xb2c39cca82539e4d,
-0x1c881e66c80d1a94,0x79ffdc889d966bb8,
-0x3e564d374e3c3ee6,0xcb3c40421fc5f5f5,
-0x34209cfccf813712,0xa2dacc7d457cfcd7,
-0x16fecfad49b01360,0x101950b7c72f629a,
-0x28a8829a078c2d86,0xdb2510f5d8ea976f,
-0xa76d1cb81bd09f4,0x69e68c3f5ab90922,
-0xdbfa17232ffaa1aa,0x9d8978748ea31b83,
-0xf9244472a9cb85d8,0x2f4ae4be0cf085ce,
-0xc7720945e7f7bb3e,0xe476a4fc1335703b,
-0xe5ac5a1461c69f4c,0x56b538369166ee76,
-0xefda8bdfe07b96b8,0x3f53b409cbdfe754,
-0xcd04d88e664ab2ca,0x8d9028c3498c7919,
-0xf35295b928768c2c,0x46ac688156498cec,
-0xd18cc6e8ae47a85e,0xf46ff44bd41a12a1,
-};
-
-
+//
+//alignas(32) const uint64_t gfCantorto2128_4R[2*(16*2*16)] = {
+//0x0,0x0,
+//0x1,0x0,
+//0x676aac9fa4b20b08,0x295ac0b1f4731af9,
+//0x676aac9fa4b20b09,0x295ac0b1f4731af9,
+//0xff1099c31bbe8f22,0xa2134422cd4054c9,
+//0xff1099c31bbe8f23,0xa2134422cd4054c9,
+//0x987a355cbf0c842a,0x8b49849339334e30,
+//0x987a355cbf0c842b,0x8b49849339334e30,
+//0x53b85b6402b1e848,0x7959d70ce1ee6942,
+//0x53b85b6402b1e849,0x7959d70ce1ee6942,
+//0x34d2f7fba603e340,0x500317bd159d73bb,
+//0x34d2f7fba603e341,0x500317bd159d73bb,
+//0xaca8c2a7190f676a,0xdb4a932e2cae3d8b,
+//0xaca8c2a7190f676b,0xdb4a932e2cae3d8b,
+//0xcbc26e38bdbd6c62,0xf210539fd8dd2772,
+//0xcbc26e38bdbd6c63,0xf210539fd8dd2772,
+//0x0,0x0,
+//0xcabcd8e4694e5644,0x8f6b313e935b8e2,
+//0x4d48b16661e860ec,0x49c9321635282198,
+//0x87f4698208a636a8,0x413f8105dc1d997a,
+//0xa13fe8ac5560ce0c,0x53d8555a9979a1c,
+//0x6b8330483c2e9848,0xdcb364640a222fe,
+//0xec7759ca3488aee0,0x4cf4b7439cbfbb84,
+//0x26cb812e5dc6f8a4,0x44020450758a0366,
+//0x5cb10fbabcf00118,0x4d52354a3a3d8c86,
+//0x960dd75ed5be575c,0x45a48659d3083464,
+//0x11f9bedcdd1861f4,0x49b075c0f15ad1e,
+//0xdb456638b45637b0,0xc6db44fe62015fc,
+//0xfd8ee716e990cf14,0x486fb01f93aa169a,
+//0x37323ff280de9950,0x4099030c7a9fae78,
+//0xb0c656708878aff8,0x1a68209a6823702,
+//0x7a7a8e94e136f9bc,0x950311a4fb78fe0,
+//0x0,0x0,
+//0xe18c55b8e07d3612,0x2ccae6ed8d6b4cd0,
+//0x588b6244c5d74470,0x210d8fbe72672c66,
+//0xb90737fc25aa7262,0xdc76953ff0c60b6,
+//0xd047dada84654da4,0xc211182c85e148b3,
+//0x31cb8f6264187bb6,0xeedbfec1088a0463,
+//0x88ccb89e41b209d4,0xe31c9792f78664d5,
+//0x6940ed26a1cf3fc6,0xcfd6717f7aed2805,
+//0xfed3b473eeb39df8,0x104d101e47f1f112,
+//0x1f5fe1cb0eceabea,0x3c87f6f3ca9abdc2,
+//0xa658d6372b64d988,0x31409fa03596dd74,
+//0x47d4838fcb19ef9a,0x1d8a794db8fd91a4,
+//0x2e946ea96ad6d05c,0xd25c0832c210b9a1,
+//0xcf183b118aabe64e,0xfe96eedf4f7bf571,
+//0x761f0cedaf01942c,0xf351878cb07795c7,
+//0x979359554f7ca23e,0xdf9b61613d1cd917,
+//0x0,0x0,
+//0xbf199eb4f675f2ac,0xce955ea0da2a682b,
+//0x19c55b8d6bef4c98,0xdbacfb2ac336178f,
+//0xa6dcc5399d9abe34,0x1539a58a191c7fa4,
+//0xf5531b28858156d0,0x58770bc4e101ab94,
+//0x4a4a859c73f4a47c,0x96e255643b2bc3bf,
+//0xec9640a5ee6e1a48,0x83dbf0ee2237bc1b,
+//0x538fde11181be8e4,0x4d4eae4ef81dd430,
+//0x8b97b65b221cc4e4,0x497f8adb47e0ae82,
+//0x348e28efd4693648,0x87ead47b9dcac6a9,
+//0x9252edd649f3887c,0x92d371f184d6b90d,
+//0x2d4b7362bf867ad0,0x5c462f515efcd126,
+//0x7ec4ad73a79d9234,0x1108811fa6e10516,
+//0xc1dd33c751e86098,0xdf9ddfbf7ccb6d3d,
+//0x6701f6fecc72deac,0xcaa47a3565d71299,
+//0xd818684a3a072c00,0x4312495bffd7ab2,
+//0x0,0x0,
+//0xa10cfc6a1654c578,0x5aa755df14f64da,
+//0xbae99a4e3fbe0c54,0x82db354523f40c7b,
+//0x1be5662429eac92c,0x87714018d2bb68a1,
+//0x8e808ec2a80c4662,0xba5ba13dbf25ee6b,
+//0x2f8c72a8be58831a,0xbff1d4604e6a8ab1,
+//0x3469148c97b24a36,0x388094789cd1e210,
+//0x9565e8e681e68f4e,0x3d2ae1256d9e86ca,
+//0x5c2b82c39ef7a93c,0x300b8602354dbc70,
+//0xfd277ea988a36c44,0x35a1f35fc402d8aa,
+//0xe6c2188da149a568,0xb2d0b34716b9b00b,
+//0x47cee4e7b71d6010,0xb77ac61ae7f6d4d1,
+//0xd2ab0c0136fbef5e,0x8a50273f8a68521b,
+//0x73a7f06b20af2a26,0x8ffa52627b2736c1,
+//0x6842964f0945e30a,0x88b127aa99c5e60,
+//0xc94e6a251f112672,0xd21672758d33aba,
+//0x0,0x0,
+//0x882e2943d5ee4534,0xc25f5e75edaa4fa9,
+//0x95d3204b1d1dd922,0x39092e35de04cc32,
+//0x1dfd0908c8f39c16,0xfb56704033ae839b,
+//0xcb6e1a7035541fd6,0x8ab363f0b1f0f211,
+//0x43403333e0ba5ae2,0x48ec3d855c5abdb8,
+//0x5ebd3a3b2849c6f4,0xb3ba4dc56ff43e23,
+//0xd6931378fda783c0,0x71e513b0825e718a,
+//0xa1318678293664f4,0xbe1eca746232042b,
+//0x291faf3bfcd821c0,0x7c4194018f984b82,
+//0x34e2a633342bbdd6,0x8717e441bc36c819,
+//0xbccc8f70e1c5f8e2,0x4548ba34519c87b0,
+//0x6a5f9c081c627b22,0x34ada984d3c2f63a,
+//0xe271b54bc98c3e16,0xf6f2f7f13e68b993,
+//0xff8cbc43017fa200,0xda487b10dc63a08,
+//0x77a29500d491e734,0xcffbd9c4e06c75a1,
+//0x0,0x0,
+//0xe684ecc9b397a5fe,0xb3b2d35103f1a3ed,
+//0x6da6f30e41a8edf0,0x34b0cc6ccf4ee620,
+//0x8b221fc7f23f480e,0x87021f3dccbf45cd,
+//0xacd605531d728f16,0xa6af6a59808b2143,
+//0x4a52e99aaee52ae8,0x151db908837a82ae,
+//0xc170f65d5cda62e6,0x921fa6354fc5c763,
+//0x27f41a94ef4dc718,0x21ad75644c34648e,
+//0x36771e3ca90ca14,0x3555819a552c1192,
+//0xe5e39d2a79076fea,0x86e752cb56ddb27f,
+//0x6ec182ed8b3827e4,0x1e54df69a62f7b2,
+//0x88456e2438af821a,0xb2579ea79993545f,
+//0xafb174b0d7e24502,0x93faebc3d5a730d1,
+//0x493598796475e0fc,0x20483892d656933c,
+//0xc21787be964aa8f2,0xa74a27af1ae9d6f1,
+//0x24936b7725dd0d0c,0x14f8f4fe1918751c,
+//0x0,0x0,
+//0xc6c1932eeb78b72a,0xeabea114c8ae9a9f,
+//0xfc5874dd3b9425ce,0x1988519c2a18a57c,
+//0x3a99e7f3d0ec92e4,0xf336f088e2b63fe3,
+//0x70ec558472062c44,0x60abfabc33f697de,
+//0xb62dc6aa997e9b6e,0x8a155ba8fb580d41,
+//0x8cb421594992098a,0x7923ab2019ee32a2,
+//0x4a75b277a2eabea0,0x939d0a34d140a83d,
+//0xa9e47128863ba654,0xdf68fe1cdf73f30,
+//0x6f25e2066d43117e,0xe7482ef50559a5af,
+//0x55bc05f5bdaf839a,0x147ede7de7ef9a4c,
+//0x937d96db56d734b0,0xfec07f692f4100d3,
+//0xd90824acf43d8a10,0x6d5d755dfe01a8ee,
+//0x1fc9b7821f453d3a,0x87e3d44936af3271,
+//0x25505071cfa9afde,0x74d524c1d4190d92,
+//0xe391c35f24d118f4,0x9e6b85d51cb7970d,
+//0x0,0x0,
+//0x8b6f419ea9e92f64,0x87506cbe98650ee9,
+//0xae03a86096676122,0xbb5791719ba8f14f,
+//0x256ce9fe3f8e4e46,0x3c07fdcf03cdffa6,
+//0xba49ef0905bed85a,0x9ae42542db02833b,
+//0x3126ae97ac57f73e,0x1db449fc43678dd2,
+//0x144a476993d9b978,0x21b3b43340aa7274,
+//0x9f2506f73a30961c,0xa6e3d88dd8cf7c9d,
+//0x997880bebf7eb61c,0xf29856ca664755b9,
+//0x1217c12016979978,0x75c83a74fe225b50,
+//0x377b28de2919d73e,0x49cfc7bbfdefa4f6,
+//0xbc14694080f0f85a,0xce9fab05658aaa1f,
+//0x23316fb7bac06e46,0x687c7388bd45d682,
+//0xa85e2e2913294122,0xef2c1f362520d86b,
+//0x8d32c7d72ca70f64,0xd32be2f926ed27cd,
+//0x65d8649854e2000,0x547b8e47be882924,
+//0x0,0x0,
+//0x16cb3187d20086c,0x9e37d35816d18239,
+//0x248c663b21703abe,0x71815387f77f4dbc,
+//0x25e0d5235c5032d2,0xefb680dfe1aecf85,
+//0x143024f5848f1090,0xa6d469fdbe031ab9,
+//0x155c97edf9af18fc,0x38e3baa5a8d29880,
+//0x30bc42cea5ff2a2e,0xd7553a7a497c5705,
+//0x31d0f1d6d8df2242,0x4962e9225fadd53c,
+//0x790935af79870be0,0x1d83ab0444495694,
+//0x786586b704a7038c,0x83b4785c5298d4ad,
+//0x5d85539458f7315e,0x6c02f883b3361b28,
+//0x5ce9e08c25d73932,0xf2352bdba5e79911,
+//0x6d39115afd081b70,0xbb57c2f9fa4a4c2d,
+//0x6c55a2428028131c,0x256011a1ec9bce14,
+//0x49b57761dc7821ce,0xcad6917e0d350191,
+//0x48d9c479a15829a2,0x54e142261be483a8,
+//0x0,0x0,
+//0xbe2444c534740484,0xcbaf5837829b974f,
+//0x5efc7f3aa24d39ca,0xf36a42b3e5f1cbbb,
+//0xe0d83bff96393d4e,0x38c51a84676a5cf4,
+//0x92372db327a9d5ee,0x1cf5645b85d85ac4,
+//0x2c13697613ddd16a,0xd75a3c6c0743cd8b,
+//0xcccb528985e4ec24,0xef9f26e86029917f,
+//0x72ef164cb190e8a0,0x24307edfe2b20630,
+//0xd48cd14917a38034,0xe374c7526e3abf93,
+//0x6aa8958c23d784b0,0x28db9f65eca128dc,
+//0x8a70ae73b5eeb9fe,0x101e85e18bcb7428,
+//0x3454eab6819abd7a,0xdbb1ddd60950e367,
+//0x46bbfcfa300a55da,0xff81a309ebe2e557,
+//0xf89fb83f047e515e,0x342efb3e69797218,
+//0x184783c092476c10,0xcebe1ba0e132eec,
+//0xa663c705a6336894,0xc744b98d8c88b9a3,
+//0x0,0x0,
+//0x2490765a301e28c2,0xb608a7b1ade6f573,
+//0xaa56dfd514863cf6,0x9ec927e0ea730849,
+//0x8ec6a98f24981434,0x28c180514795fd3a,
+//0xb493920663b35d20,0xf2eee16207fa6641,
+//0x9003e45c53ad75e2,0x44e646d3aa1c9332,
+//0x1ec54dd3773561d6,0x6c27c682ed896e08,
+//0x3a553b89472b4914,0xda2f6133406f9b7b,
+//0x9b78c9542bba3a2e,0x79c54cdd0e226966,
+//0xbfe8bf0e1ba412ec,0xcfcdeb6ca3c49c15,
+//0x312e16813f3c06d8,0xe70c6b3de451612f,
+//0x15be60db0f222e1a,0x5104cc8c49b7945c,
+//0x2feb5b524809670e,0x8b2badbf09d80f27,
+//0xb7b2d0878174fcc,0x3d230a0ea43efa54,
+//0x85bd84875c8f5bf8,0x15e28a5fe3ab076e,
+//0xa12df2dd6c91733a,0xa3ea2dee4e4df21d,
+//0x0,0x0,
+//0x456895c1d95fe234,0xee72b1a21497e77b,
+//0x4eb77b48cc5f7038,0x9ad3c105b155ffef,
+//0xbdfee891500920c,0x74a170a7a5c21894,
+//0x68f65fa05931208c,0x585b4042d008c9da,
+//0x2d9eca61806ec2b8,0xb629f1e0c49f2ea1,
+//0x264124e8956e50b4,0xc2888147615d3635,
+//0x6329b1294c31b280,0x2cfa30e575cad14e,
+//0x16dde2bb2b38dcfa,0xaeca82ee463b0b3b,
+//0x53b5777af2673ece,0x40b8334c52acec40,
+//0x586a99f3e767acc2,0x341943ebf76ef4d4,
+//0x1d020c323e384ef6,0xda6bf249e3f913af,
+//0x7e2bbd1b7209fc76,0xf691c2ac9633c2e1,
+//0x3b4328daab561e42,0x18e3730e82a4259a,
+//0x309cc653be568c4e,0x6c4203a927663d0e,
+//0x75f4539267096e7a,0x8230b20b33f1da75,
+//0x0,0x0,
+//0x3904c8d2f5c3d2d6,0x54d2b7c147b9eab0,
+//0x8b1c8bd76f237756,0x4d81761ce690153e,
+//0xb21843059ae0a580,0x1953c1dda129ff8e,
+//0x8a2133f2160fc5ec,0x614a21c3ff3bf28a,
+//0xb325fb20e3cc173a,0x35989602b882183a,
+//0x13db825792cb2ba,0x2ccb57df19abe7b4,
+//0x383970f78cef606c,0x7819e01e5e120d04,
+//0x4b053b0413b7ed2a,0xa7cdb8c6809748d7,
+//0x7201f3d6e6743ffc,0xf31f0f07c72ea267,
+//0xc019b0d37c949a7c,0xea4cceda66075de9,
+//0xf91d7801895748aa,0xbe9e791b21beb759,
+//0xc12408f605b828c6,0xc68799057facba5d,
+//0xf820c024f07bfa10,0x92552ec4381550ed,
+//0x4a3883216a9b5f90,0x8b06ef19993caf63,
+//0x733c4bf39f588d46,0xdfd458d8de8545d3,
+//0x0,0x0,
+//0x14e4307f9d1772b6,0x515219ca23f9ce5c,
+//0x511e34506522e6ae,0x8247627f48ff1f7f,
+//0x45fa042ff8359418,0xd3157bb56b06d123,
+//0xe3a3756c6efacfc4,0xf788c793e7244e9f,
+//0xf7474513f3edbd72,0xa6dade59c4dd80c3,
+//0xb2bd413c0bd8296a,0x75cfa5ecafdb51e0,
+//0xa659714396cf5bdc,0x249dbc268c229fbc,
+//0x5a70839fc81fb4c0,0xd35f0eb88cae752b,
+//0x4e94b3e05508c676,0x820d1772af57bb77,
+//0xb6eb7cfad3d526e,0x51186cc7c4516a54,
+//0x1f8a87b0302a20d8,0x4a750de7a8a408,
+//0xb9d3f6f3a6e57b04,0x24d7c92b6b8a3bb4,
+//0xad37c68c3bf209b2,0x7585d0e14873f5e8,
+//0xe8cdc2a3c3c79daa,0xa690ab54237524cb,
+//0xfc29f2dc5ed0ef1c,0xf7c2b29e008cea97,
+//0x0,0x0,
+//0xda8e23483a97853a,0x38f065e6ec77c32c,
+//0xd1700ce51721220c,0xee558f30070e0c3d,
+//0xbfe2fad2db6a736,0xd6a5ead6eb79cf11,
+//0x249484a90e31ef88,0xd78f250953e96933,
+//0xfe1aa7e134a66ab2,0xef7f40efbf9eaa1f,
+//0xf5e4884c1910cd84,0x39daaa3954e7650e,
+//0x2f6aab04238748be,0x12acfdfb890a622,
+//0x771a1494d77054ac,0xde34b71e0312848f,
+//0xad9437dcede7d196,0xe6c4d2f8ef6547a3,
+//0xa66a1871c05176a0,0x3061382e041c88b2,
+//0x7ce43b39fac6f39a,0x8915dc8e86b4b9e,
+//0x538e903dd941bb24,0x9bb921750fbedbc,
+//0x8900b375e3d63e1e,0x314bf7f1bc8c2e90,
+//0x82fe9cd8ce609928,0xe7ee1d2757f5e181,
+//0x5870bf90f4f71c12,0xdf1e78c1bb8222ad,
+//0x0,0x0,
+//0x27f349141093e620,0x97e14e9448decae7,
+//0x8da828e52be94d70,0x928de3c8e22c0f1d,
+//0xaa5b61f13b7aab50,0x56cad5caaf2c5fa,
+//0xc1e9db8ac9f1c256,0xba586143dfe63deb,
+//0xe61a929ed9622476,0x2db92fd79738f70c,
+//0x4c41f36fe2188f26,0x28d5828b3dca32f6,
+//0x6bb2ba7bf28b6906,0xbf34cc1f7514f811,
+//0xd9b45813424b2b38,0xb2052ca6fb35eaa9,
+//0xfe47110752d8cd18,0x25e46232b3eb204e,
+//0x541c70f669a26648,0x2088cf6e1919e5b4,
+//0x73ef39e279318068,0xb76981fa51c72f53,
+//0x185d83998bbae96e,0x85d4de524d3d742,
+//0x3faeca8d9b290f4e,0x9fbc03716c0d1da5,
+//0x95f5ab7ca053a41e,0x9ad0ae2dc6ffd85f,
+//0xb206e268b0c0423e,0xd31e0b98e2112b8,
+//0x0,0x0,
+//0x10f28ab6172a4efa,0x794a2a7c84a76d2c,
+//0x213491af2f858c38,0xa3fb2735d34fbaa7,
+//0x31c61b1938afc2c2,0xdab10d4957e8d78b,
+//0xdd93cc151a20dcda,0xfa7ca4a3574c6525,
+//0xcd6146a30d0a9220,0x83368edfd3eb0809,
+//0xfca75dba35a550e2,0x598783968403df82,
+//0xec55d70c228f1e18,0x20cda9ea00a4b2ae,
+//0x3190a2225ab65e2c,0xff5e390da90f4835,
+//0x216228944d9c10d6,0x861413712da82519,
+//0x10a4338d7533d214,0x5ca51e387a40f292,
+//0x56b93b62199cee,0x25ef3444fee79fbe,
+//0xec036e37409682f6,0x5229daefe432d10,
+//0xfcf1e48157bccc0c,0x7c68b7d27ae4403c,
+//0xcd37ff986f130ece,0xa6d9ba9b2d0c97b7,
+//0xddc5752e78394034,0xdf9390e7a9abfa9b,
+//0x0,0x0,
+//0x71389b2a8246f5e4,0xd79573b001f21771,
+//0x6ae0532ae2bbfb90,0xdfd3122b95e92c4f,
+//0x1bd8c80060fd0e74,0x846619b941b3b3e,
+//0xcd6b22d4c21c7758,0x59ee81e35141d3cc,
+//0xbc53b9fe405a82bc,0x8e7bf25350b3c4bd,
+//0xa78b71fe20a78cc8,0x863d93c8c4a8ff83,
+//0xd6b3ead4a2e1792c,0x51a8e078c55ae8f2,
+//0x85e338536eb1bbc,0xca785a7f809253d7,
+//0x7966a8afb4adee58,0x1ded29cf816044a6,
+//0x62be60afd450e02c,0x15ab4854157b7f98,
+//0x1386fb85561615c8,0xc23e3be4148968e9,
+//0xc5351151f4f76ce4,0x9396db9cd1d3801b,
+//0xb40d8a7b76b19900,0x4403a82cd021976a,
+//0xafd5427b164c9774,0x4c45c9b7443aac54,
+//0xdeedd951940a6290,0x9bd0ba0745c8bb25,
+//0x0,0x0,
+//0xa602f3fd08bbca2a,0x3cf77b9a1ded625a,
+//0x9cfb59155f2c296a,0xc74456a7f1e3b58b,
+//0x3af9aae85797e340,0xfbb32d3dec0ed7d1,
+//0xbc92de7f7ebfd6c4,0x38ff17882d7d411c,
+//0x1a902d8276041cee,0x4086c1230902346,
+//0x2069876a2193ffae,0xffbb412fdc9ef497,
+//0x866b749729283584,0xc34c3ab5c17396cd,
+//0x49dd31700df81d26,0x6daab92652394278,
+//0xefdfc28d0543d70c,0x515dc2bc4fd42022,
+//0xd526686552d4344c,0xaaeeef81a3daf7f3,
+//0x73249b985a6ffe66,0x9619941bbe3795a9,
+//0xf54fef0f7347cbe2,0x5555aeae7f440364,
+//0x534d1cf27bfc01c8,0x69a2d53462a9613e,
+//0x69b4b61a2c6be288,0x9211f8098ea7b6ef,
+//0xcfb645e724d028a2,0xaee68393934ad4b5,
+//0x0,0x0,
+//0x3b8f902c0a858e4e,0x8b95b6a7427690cb,
+//0xd525a8185f8af324,0xf31f1e9daabbff9f,
+//0xeeaa3834550f7d6a,0x788aa83ae8cd6f54,
+//0x17f87f09bc736f26,0xfafd49e2ee8251e9,
+//0x2c77ef25b6f6e168,0x7168ff45acf4c122,
+//0xc2ddd711e3f99c02,0x9e2577f4439ae76,
+//0xf952473de97c124c,0x8277e1d8064f3ebd,
+//0xae5fb3551c95931e,0x1863362e3ae97756,
+//0x95d0237916101d50,0x93f68089789fe79d,
+//0x7b7a1b4d431f603a,0xeb7c28b3905288c9,
+//0x40f58b61499aee74,0x60e99e14d2241802,
+//0xb9a7cc5ca0e6fc38,0xe29e7fccd46b26bf,
+//0x82285c70aa637276,0x690bc96b961db674,
+//0x6c826444ff6c0f1c,0x118161517ed0d920,
+//0x570df468f5e98152,0x9a14d7f63ca649eb,
+//0x0,0x0,
+//0x9b8f8f876479058e,0xcad343e8080cba83,
+//0x51bbcc440c472768,0xf2e5a279864a60f5,
+//0xca3443c3683e22e6,0x3836e1918e46da76,
+//0x6340402c3f7ffebe,0xb70b9103d1cd6617,
+//0xf8cfcfab5b06fb30,0x7dd8d2ebd9c1dc94,
+//0x32fb8c683338d9d6,0x45ee337a578706e2,
+//0xa97403ef5741dc58,0x8f3d70925f8bbc61,
+//0xdeb9ef235f15ff90,0xb7959b94e1e22d49,
+//0x453660a43b6cfa1e,0x7d46d87ce9ee97ca,
+//0x8f0223675352d8f8,0x457039ed67a84dbc,
+//0x148dace0372bdd76,0x8fa37a056fa4f73f,
+//0xbdf9af0f606a012e,0x9e0a97302f4b5e,
+//0x26762088041304a0,0xca4d497f3823f1dd,
+//0xec42634b6c2d2646,0xf27ba8eeb6652bab,
+//0x77cdeccc085423c8,0x38a8eb06be699128,
+//0x0,0x0,
+//0x5a9d3675a3531196,0x3524ce9c7f7b56e2,
+//0xce10620e568164c2,0x8ef7ee5cecdb882d,
+//0x948d547bf5d27554,0xbbd320c093a0decf,
+//0x854d0fea22c345b2,0xda3844c594d764bf,
+//0xdfd0399f81905424,0xef1c8a59ebac325d,
+//0x4b5d6de474422170,0x54cfaa99780cec92,
+//0x11c05b91d71130e6,0x61eb64050777ba70,
+//0x16c016c2d631ae74,0xf2328df87cdf3e71,
+//0x4c5d20b77562bfe2,0xc716436403a46893,
+//0xd8d074cc80b0cab6,0x7cc563a49004b65c,
+//0x824d42b923e3db20,0x49e1ad38ef7fe0be,
+//0x938d1928f4f2ebc6,0x280ac93de8085ace,
+//0xc9102f5d57a1fa50,0x1d2e07a197730c2c,
+//0x5d9d7b26a2738f04,0xa6fd276104d3d2e3,
+//0x7004d5301209e92,0x93d9e9fd7ba88401,
+//0x0,0x0,
+//0x3a9122c15f3ab78,0x9eb8b35a2448eeff,
+//0x4ac1ab2d94aa463e,0x3c449b0a0456c972,
+//0x4968b9018159ed46,0xa2fc2850201e278d,
+//0x70d846ae38ffb938,0x6cddd4542b3a7254,
+//0x737154822d0c1240,0xf265670e0f729cab,
+//0x3a19ed83ac55ff06,0x50994f5e2f6cbb26,
+//0x39b0ffafb9a6547e,0xce21fc040b2455d9,
+//0x3f1ab33bdd022656,0xee26c355dcac88cf,
+//0x3cb3a117c8f18d2e,0x709e700ff8e46630,
+//0x75db181649a86068,0xd262585fd8fa41bd,
+//0x76720a3a5c5bcb10,0x4cdaeb05fcb2af42,
+//0x4fc2f595e5fd9f6e,0x82fb1701f796fa9b,
+//0x4c6be7b9f00e3416,0x1c43a45bd3de1464,
+//0x5035eb87157d950,0xbebf8c0bf3c033e9,
+//0x6aa4c9464a47228,0x20073f51d788dd16,
+//0x0,0x0,
+//0xa2def1742f3b5916,0x55fe928ccc907446,
+//0xc0536b0be526eb6,0xce0290a08ea7ed67,
+//0xaedbc7c4916937a0,0x9bfc022c42379921,
+//0x63118f8310afbd9c,0xf3bfe1a1625671ef,
+//0xc1cf7ef73f94e48a,0xa641732daec605a9,
+//0x6f14b933aefdd32a,0x3dbd7101ecf19c88,
+//0xcdca484781c68a3c,0x6843e38d2061e8ce,
+//0x5c5ad70dd7f32ae,0xfbdcaf23d12e7a5d,
+//0xa71b5c04f2446bb8,0xae223daf1dbe0e1b,
+//0x9c09bc0632d5c18,0x35de3f835f89973a,
+//0xab1e6ab44c16050e,0x6020ad0f9319e37c,
+//0x66d422f3cdd08f32,0x8634e82b3780bb2,
+//0xc40ad387e2ebd624,0x5d9ddc0e7fe87ff4,
+//0x6ad114437382e184,0xc661de223ddfe6d5,
+//0xc80fe5375cb9b892,0x939f4caef14f9293,
+//0x0,0x0,
+//0x2cd73c266f68da36,0x9bfcfcadd6ed8b57,
+//0x6d8e1fe42b061d44,0x3db9c6976df592a6,
+//0x415923c2446ec772,0xa6453a3abb1819f1,
+//0x80ca05549a4dc27c,0xc75a42071ff8895d,
+//0xac1d3972f525184a,0x5ca6beaac915020a,
+//0xed441ab0b14bdf38,0xfae38490720d1bfb,
+//0xc1932696de23050e,0x611f783da4e090ac,
+//0xd1fbff53b9e5b9a0,0x11f736abdbe2672a,
+//0xfd2cc375d68d6396,0x8a0bca060d0fec7d,
+//0xbc75e0b792e3a4e4,0x2c4ef03cb617f58c,
+//0x90a2dc91fd8b7ed2,0xb7b20c9160fa7edb,
+//0x5131fa0723a87bdc,0xd6ad74acc41aee77,
+//0x7de6c6214cc0a1ea,0x4d51880112f76520,
+//0x3cbfe5e308ae6698,0xeb14b23ba9ef7cd1,
+//0x1068d9c567c6bcae,0x70e84e967f02f786,
+//0x0,0x0,
+//0xc1ca004429d1c70c,0x83670004dbe27f63,
+//0x7ade7ba41da719e2,0x75ff5173392ad2ea,
+//0xbb147be03476deee,0xf6985177e2c8ad89,
+//0x2da0b1432202bae2,0xc33784b9b478b88b,
+//0xec6ab1070bd37dee,0x405084bd6f9ac7e8,
+//0x577ecae73fa5a300,0xb6c8d5ca8d526a61,
+//0x96b4caa31674640c,0x35afd5ce56b01502,
+//0x88cc8045cdff4040,0x39324dfdad64aa8e,
+//0x49068001e42e874c,0xba554df97686d5ed,
+//0xf212fbe1d05859a2,0x4ccd1c8e944e7864,
+//0x33d8fba5f9899eae,0xcfaa1c8a4fac0707,
+//0xa56c3106effdfaa2,0xfa05c944191c1205,
+//0x64a63142c62c3dae,0x7962c940c2fe6d66,
+//0xdfb24aa2f25ae340,0x8ffa98372036c0ef,
+//0x1e784ae6db8b244c,0xc9d9833fbd4bf8c,
+//0x0,0x0,
+//0xd1537109b42cc8a0,0x8b6232e621520ca1,
+//0xc5585ec70c29b8f0,0x961f8facdb0ea92d,
+//0x140b2fceb8057050,0x1d7dbd4afa5ca58c,
+//0x641e0bbe37274246,0x38e42a8ae4b60f8e,
+//0xb54d7ab7830b8ae6,0xb386186cc5e4032f,
+//0xa14655793b0efab6,0xaefba5263fb8a6a3,
+//0x701524708f223216,0x259997c01eeaaa02,
+//0xb1f69a8517d41456,0xc70e543a5a80f74b,
+//0x60a5eb8ca3f8dcf6,0x4c6c66dc7bd2fbea,
+//0x74aec4421bfdaca6,0x5111db96818e5e66,
+//0xa5fdb54bafd16406,0xda73e970a0dc52c7,
+//0xd5e8913b20f35610,0xffea7eb0be36f8c5,
+//0x4bbe03294df9eb0,0x74884c569f64f464,
+//0x10b0cffc2cdaeee0,0x69f5f11c653851e8,
+//0xc1e3bef598f62640,0xe297c3fa446a5d49,
+//0x0,0x0,
+//0xbccf8ca839bfe3a8,0x38bd7652fbb4463c,
+//0xc4fab69066e3433a,0xefa5f7ca9f6294c1,
+//0x78353a385f5ca092,0xd718819864d6d2fd,
+//0xb54afad4cd1155a8,0x31317c030896c74a,
+//0x985767cf4aeb600,0x98c0a51f3228176,
+//0x71b04c44abf21692,0xde948bc997f4538b,
+//0xcd7fc0ec924df53a,0xe629fd9b6c4015b7,
+//0x7d4bba2cbae355d4,0xd5fb04e16da98b6,
+//0xc1843684835cb67c,0x35e2c61ced6ede8a,
+//0xb9b10cbcdc0016ee,0xe2fa478489b80c77,
+//0x57e8014e5bff546,0xda4731d6720c4a4b,
+//0xc80140f877f2007c,0x3c6ecc4d1e4c5ffc,
+//0x74cecc504e4de3d4,0x4d3ba1fe5f819c0,
+//0xcfbf66811114346,0xd3cb3b87812ecb3d,
+//0xb0347ac028aea0ee,0xeb764dd57a9a8d01,
+//0x0,0x0,
+//0xfd2b185552fcca1e,0xaf27a2c3c9af3b15,
+//0xa74e3032c1c70940,0xb22c87060644347d,
+//0x5a652867933bc35e,0x1d0b25c5cfeb0f68,
+//0x96784c18fa9a222c,0x9f1317dd9bd62b2b,
+//0x6b53544da866e832,0x3034b51e5279103e,
+//0x31367c2a3b5d2b6c,0x2d3f90db9d921f56,
+//0xcc1d647f69a1e172,0x82183218543d2443,
+//0xa055412a1255732c,0x9675e5102f20a86d,
+//0x5d7e597f40a9b932,0x395247d3e68f9378,
+//0x71b7118d3927a6c,0x2459621629649c10,
+//0xfa30694d816eb072,0x8b7ec0d5e0cba705,
+//0x362d0d32e8cf5100,0x966f2cdb4f68346,
+//0xcb061567ba339b1e,0xa641500e7d59b853,
+//0x91633d0029085840,0xbb4a75cbb2b2b73b,
+//0x6c4825557bf4925e,0x146dd7087b1d8c2e,
+//0x0,0x0,
+//0xbd9e54181b305f0,0x1196f9167176350a,
+//0x2de9c7568ec18048,0x4c7d6f6a66426bc8,
+//0x263022170f7285b8,0x5deb967c17345ec2,
+//0xf69478d0555733be,0x2cf2076679e35cae,
+//0xfd4d9d91d4e4364e,0x3d64fe70089569a4,
+//0xdb7dbf86db96b3f6,0x608f680c1fa13766,
+//0xd0a45ac75a25b606,0x7119911a6ed7026c,
+//0xa0dea3eaee857928,0xeff27f24fdcf1cb1,
+//0xab0746ab6f367cd8,0xfe6486328cb929bb,
+//0x8d3764bc6044f960,0xa38f104e9b8d7779,
+//0x86ee81fde1f7fc90,0xb219e958eafb4273,
+//0x564adb3abbd24a96,0xc3007842842c401f,
+//0x5d933e7b3a614f66,0xd2968154f55a7515,
+//0x7ba31c6c3513cade,0x8f7d1728e26e2bd7,
+//0x707af92db4a0cf2e,0x9eebee3e93181edd,
+//0x0,0x0,
+//0x22de535186312472,0xb2c39cca82539e4d,
+//0x1c881e66c80d1a94,0x79ffdc889d966bb8,
+//0x3e564d374e3c3ee6,0xcb3c40421fc5f5f5,
+//0x34209cfccf813712,0xa2dacc7d457cfcd7,
+//0x16fecfad49b01360,0x101950b7c72f629a,
+//0x28a8829a078c2d86,0xdb2510f5d8ea976f,
+//0xa76d1cb81bd09f4,0x69e68c3f5ab90922,
+//0xdbfa17232ffaa1aa,0x9d8978748ea31b83,
+//0xf9244472a9cb85d8,0x2f4ae4be0cf085ce,
+//0xc7720945e7f7bb3e,0xe476a4fc1335703b,
+//0xe5ac5a1461c69f4c,0x56b538369166ee76,
+//0xefda8bdfe07b96b8,0x3f53b409cbdfe754,
+//0xcd04d88e664ab2ca,0x8d9028c3498c7919,
+//0xf35295b928768c2c,0x46ac688156498cec,
+//0xd18cc6e8ae47a85e,0xf46ff44bd41a12a1,
+//};
+//
+//
-uint64_t gfCantorto2128_8R[2*(8*256)] __attribute__((aligned(32))) = {
+alignas(32) const uint64_t gfCantorto2128_8R[2*(8*256)] = {
0x0,0x0,
0x1,0x0,
0x676aac9fa4b20b08,0x295ac0b1f4731af9,
@@ -2344,3 +2344,4 @@ uint64_t gfCantorto2128_8R[2*(8*256)] __attribute__((aligned(32))) = {
0x218644e1b29bb006,0x3921a27a065e41fc,
0xc702a828010c15f8,0x8a93712b05afe211,
};
+}
diff --git a/gf264_cantor_iso.c b/bitpolymul/gf264_cantor_iso.h
similarity index 90%
rename from gf264_cantor_iso.c
rename to bitpolymul/gf264_cantor_iso.h
index 7fa1b87..0ec20d7 100644
--- a/gf264_cantor_iso.c
+++ b/bitpolymul/gf264_cantor_iso.h
@@ -18,9 +18,10 @@ along with BitPolyMul. If not, see .
*/
#include "stdint.h"
+#include "bpmDefines.h"
+namespace bpm{
-
-uint64_t gfCantorto264[64*2] __attribute__((aligned(32))) = {
+alignas(32) const uint64_t gfCantorto264[64*2] = {
0x1, 0,
0x19C9369F278ADC02, 0,
0xA181E7D66F5FF794, 0,
@@ -88,270 +89,9 @@ uint64_t gfCantorto264[64*2] __attribute__((aligned(32))) = {
};
-#if 0
-uint64_t gfCantorto264_4R[(64/4)*16] __attribute__((aligned(32))) = {
-0x0,
-0x1,
-0x19c9369f278adc02,
-0x19c9369f278adc03,
-0xa181e7d66f5ff794,
-0xa181e7d66f5ff795,
-0xb848d14948d52b96,
-0xb848d14948d52b97,
-0x5db84357ce785d08,
-0x5db84357ce785d09,
-0x447175c8e9f2810a,
-0x447175c8e9f2810b,
-0xfc39a481a127aa9c,
-0xfc39a481a127aa9d,
-0xe5f0921e86ad769e,
-0xe5f0921e86ad769f,
-0x0,
-0xb973d466f5c9d0ca,
-0x521ac889831a075e,
-0xeb691cef76d3d794,
-0x33ce8beddc8a656,
-0xba4f3cd82801769c,
-0x512620375ed2a108,
-0xe855f451ab1b71c2,
-0xb5846c4e07b91010,
-0xcf7b828f270c0da,
-0xe79ea4c784a3174e,
-0x5eed70a1716ac784,
-0xb6b884f0da71b646,
-0xfcb50962fb8668c,
-0xe4a24c79596bb118,
-0x5dd1981faca261d2,
-0x0,
-0x4087b8cbb37a32ec,
-0xd0d3888c0ae17c,
-0x40576b433f70d390,
-0xafd5ac70237f2222,
-0xef5214bb900510ce,
-0xaf057ff8af75c35e,
-0xef82c7331c0ff1b2,
-0xe3f5af99cc3aaaf8,
-0xa37217527f409814,
-0xe3257c1140304b84,
-0xa3a2c4daf34a7968,
-0x4c2003e9ef4588da,
-0xca7bb225c3fba36,
-0x4cf0d061634f69a6,
-0xc7768aad0355b4a,
-0x0,
-0x5a1db3b16a0b58b8,
-0x9947c54fe7ee248,
-0x5389cfe59475baf0,
-0xe8eaf0e0068f544,
-0x54931cbf6a63adfc,
-0x71ad35afe16170c,
-0x5d0760eb941d4fb4,
-0xa2a113500b4b4f5a,
-0xf8bca0e1614017e2,
-0xab356f04f535ad12,
-0xf128dcb59f3ef5aa,
-0xac2fbc5e0b23ba1e,
-0xf6320fef6128e2a6,
-0xa5bbc00af55d5856,
-0xffa673bb9f5600ee,
-0x0,
-0xe96f9805d6ce0bb0,
-0x53496f8b5c9edd4c,
-0xba26f78e8a50d6fc,
-0xad325cb6f4ac2a9e,
-0x445dc4b32262212e,
-0xfe7b333da832f7d2,
-0x1714ab387efcfc62,
-0x4a8dcf8bd7ede826,
-0xa3e2578e0123e396,
-0x19c4a0008b73356a,
-0xf0ab38055dbd3eda,
-0xe7bf933d2341c2b8,
-0xed00b38f58fc908,
-0xb4f6fcb67fdf1ff4,
-0x5d9964b3a9111444,
-0x0,
-0xa3e9c552b6434210,
-0x5fa92ad9c9bc7ed0,
-0xfc40ef8b7fff3cc0,
-0xa389f910cd7734de,
-0x603c427b3476ce,
-0xfc20d3c904cb4a0e,
-0x5fc9169bb288081e,
-0xe916f3dfca4609d8,
-0x4aff368d7c054bc8,
-0xb6bfd90603fa7708,
-0x15561c54b5b93518,
-0x4a9f0acf07313d06,
-0xe976cf9db1727f16,
-0x15362016ce8d43d6,
-0xb6dfe54478ce01c6,
-0x0,
-0xf89578714bd28f96,
-0x564dda59237a3352,
-0xaed8a22868a8bcc4,
-0xad33bc6cc75aed38,
-0x55a6c41d8c8862ae,
-0xfb7e6635e420de6a,
-0x3eb1e44aff251fc,
-0x57a3104fcd0e5f34,
-0xaf36683e86dcd0a2,
-0x1eeca16ee746c66,
-0xf97bb267a5a6e3f0,
-0xfa90ac230a54b20c,
-0x205d45241863d9a,
-0xacdd767a292e815e,
-0x54480e0b62fc0ec8,
-0x0,
-0xb0f502e4cd60039a,
-0xeb42e79f91f49f8c,
-0x5bb7e57b5c949c16,
-0x54e5bf3774b3f850,
-0xe410bdd3b9d3fbca,
-0xbfa758a8e54767dc,
-0xf525a4c28276446,
-0xb66864e6ec14b4d2,
-0x69d66022174b748,
-0x5d2a83797de02b5e,
-0xeddf819db08028c4,
-0xe28ddbd198a74c82,
-0x5278d93555c74f18,
-0x9cf3c4e0953d30e,
-0xb93a3eaac433d094,
-0x0,
-0xed57ce778f0d6244,
-0x523aaf9d6148ba24,
-0xbf6d61eaee45d860,
-0xa8fcbfaac14940c6,
-0x45ab71dd4e442282,
-0xfac61037a001fae2,
-0x1791de402f0c98a6,
-0xe503eacfcef77780,
-0x85424b841fa15c4,
-0xb7394552afbfcda4,
-0x5a6e8b2520b2afe0,
-0x4dff55650fbe3746,
-0xa0a89b1280b35502,
-0x1fc5faf86ef68d62,
-0xf292348fe1fbef26,
-0x0,
-0xf3746c7b5183a372,
-0xec50d77d2f416218,
-0x1f24bb067ec2c16a,
-0xf9cdf54569fe87e6,
-0xab9993e387d2494,
-0x159d223846bfe5fe,
-0xe6e94e43173c468c,
-0xe576269915705e2c,
-0x16024ae244f3fd5e,
-0x926f1e43a313c34,
-0xfa529d9f6bb29f46,
-0x1cbbd3dc7c8ed9ca,
-0xefcfbfa72d0d7ab8,
-0xf0eb04a153cfbbd2,
-0x39f68da024c18a0,
-0x0,
-0xee2a197148fa8c72,
-0x49e31453575f365a,
-0xa7c90d221fa5ba28,
-0xb86698d88add0bc0,
-0x564c81a9c22787b2,
-0xf1858c8bdd823d9a,
-0x1faf95fa9578b1e8,
-0x4f35fb218e7f37c0,
-0xa11fe250c685bbb2,
-0x6d6ef72d920019a,
-0xe8fcf60391da8de8,
-0xf75363f904a23c00,
-0x19797a884c58b072,
-0xbeb077aa53fd0a5a,
-0x509a6edb1b078628,
-0x0,
-0xa306feea8a242832,
-0x5e5f06a9daead6e6,
-0xfd59f84350cefed4,
-0xbe13089ecc784ea0,
-0x1d15f674465c6692,
-0xe04c0e3716929846,
-0x434af0dd9cb6b074,
-0xfe1a10738739c892,
-0x5d1cee990d1de0a0,
-0xa04516da5dd31e74,
-0x343e830d7f73646,
-0x400918ed4b418632,
-0xe30fe607c165ae00,
-0x1e561e4491ab50d4,
-0xbd50e0ae1b8f78e6,
-0x0,
-0xe2266ceb0c5bc774,
-0xf490e6ed40d1dd1a,
-0x16b68a064c8a1a6e,
-0xf3f5f515077e92f0,
-0x11d399fe0b255584,
-0x76513f847af4fea,
-0xe5437f134bf4889e,
-0x467c20312e7eb0f0,
-0xa45a4cda22257784,
-0xb2ecc6dc6eaf6dea,
-0x50caaa3762f4aa9e,
-0xb589d52429002200,
-0x57afb9cf255be574,
-0x411933c969d1ff1a,
-0xa33f5f22658a386e,
-0x0,
-0xb06caa4295d350c2,
-0x5c5916d98a583c16,
-0xec35bc9b1f8b6cd4,
-0xa04de5b4c7a1ceac,
-0x10214ff652729e6e,
-0xfc14f36d4df9f2ba,
-0x4c78592fd82aa278,
-0x41430183d6e85ec0,
-0xf12fabc1433b0e02,
-0x1d1a175a5cb062d6,
-0xad76bd18c9633214,
-0xe10ee4371149906c,
-0x51624e75849ac0ae,
-0xbd57f2ee9b11ac7a,
-0xd3b58ac0ec2fcb8,
-0x0,
-0xb361d8dabe3b3632,
-0x4357375d88b88b56,
-0xf036ef873683bd64,
-0xb057dcc8a19fbc9c,
-0x33604121fa48aae,
-0xf300eb95292737ca,
-0x4061334f971c01f8,
-0xf26e1791be4b37c2,
-0x410fcf4b007001f0,
-0xb13920cc36f3bc94,
-0x258f81688c88aa6,
-0x4239cb591fd48b5e,
-0xf1581383a1efbd6c,
-0x16efc04976c0008,
-0xb20f24de2957363a,
-0x0,
-0xe9f744031bfe63e4,
-0xe50803875e9ab776,
-0xcff47844564d492,
-0x44ee098f4d56753e,
-0xad194d8c56a816da,
-0xa1e60a0813ccc248,
-0x48114e0b0832a1ac,
-0x9dc338f8399031b4,
-0x74347cfb226e5250,
-0x78cb3b7f670a86c2,
-0x913c7f7c7cf4e526,
-0xd92d317774c6448a,
-0x30da75746f38276e,
-0x3c2532f02a5cf3fc,
-0xd5d276f331a29018,
-};
-#endif
-
-uint64_t gfCantorto264_8R[(64/8)*256*2] __attribute__((aligned(32))) = {
+alignas(32) const uint64_t gfCantorto264_8R[(64/8)*256*2] = {
0x0,0,
0x1,0,
0x19c9369f278adc02,0,
@@ -2401,4 +2141,5 @@ uint64_t gfCantorto264_8R[(64/8)*256*2] __attribute__((aligned(32))) = {
0xd4bc8af7a6ce9010,0,
0x67dd522d18f5a622,0,
};
+}
diff --git a/bitpolymul/gfext_aesni.h b/bitpolymul/gfext_aesni.h
new file mode 100644
index 0000000..a2cfd41
--- /dev/null
+++ b/bitpolymul/gfext_aesni.h
@@ -0,0 +1,271 @@
+#pragma once
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+
+#include
+#include
+#include "bpmDefines.h"
+
+namespace bpm {
+//
+// /// X^64 + X^4 + X^3 + X + 1
+// /// 0x1b
+ alignas(32) const uint64_t _gf2ext64_reducer[4] = { 0x415A776C2D361B00ULL,0x1bULL,0x415A776C2D361B00ULL,0x1bULL };
+
+ inline
+ __m128i _gf2ext64_reduce_sse(__m128i x0)
+ {
+ __m128i reducer = _mm_load_si128((__m128i const*)_gf2ext64_reducer);
+ //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
+ __m128i r0 = _mm_clmulepi64_si128(x0, reducer, 0x11);
+ __m128i r1 = _mm_shuffle_epi8(reducer, r0);
+ __m128i r2 = _mm_xor_si128(x0, r0);
+ r1 = _mm_xor_si128(r1, _mm_slli_si128(r2, 8));
+ return _mm_srli_si128(r1, 8);
+ }
+
+
+ inline
+ __m128i _gf2ext64_reduce_x2_sse(__m128i x0, __m128i y0)
+ {
+ __m128i reducer = _mm_load_si128((__m128i const*)_gf2ext64_reducer);
+ //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
+ __m128i r0 = _mm_clmulepi64_si128(x0, reducer, 0x11);
+ __m128i s0 = _mm_clmulepi64_si128(y0, reducer, 0x11);
+ __m128i r2 = _mm_xor_si128(x0, r0);
+ __m128i s2 = _mm_xor_si128(y0, s0);
+ __m128i pr = _mm_unpacklo_epi64(r2, s2);
+
+ __m128i rr = _mm_unpackhi_epi64(r0, s0);
+ __m128i rr2 = _mm_shuffle_epi8(reducer, rr);
+
+ return _mm_xor_si128(pr, rr2);
+ }
+//
+ inline
+ __m256i _gf2ext64_reduce_x4_avx2(__m128i w0, __m128i x0, __m128i y0, __m128i z0)
+ {
+ __m256i reducer2 = _mm256_load_si256((__m256i const*)_gf2ext64_reducer);
+ //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
+ __m128i reducer = _mm256_castsi256_si128(reducer2);
+ __m128i r0 = _mm_clmulepi64_si128(w0, reducer, 0x11);
+ __m128i s0 = _mm_clmulepi64_si128(x0, reducer, 0x11);
+ __m128i t0 = _mm_clmulepi64_si128(y0, reducer, 0x11);
+ __m128i u0 = _mm_clmulepi64_si128(z0, reducer, 0x11);
+ __m128i r2 = _mm_xor_si128(w0, r0);
+ __m128i s2 = _mm_xor_si128(x0, s0);
+ __m128i t2 = _mm_xor_si128(y0, t0);
+ __m128i u2 = _mm_xor_si128(z0, u0);
+ __m256i pr1 = _mm256_castsi128_si256(_mm_unpacklo_epi64(r2, s2));
+ __m256i pr2 = _mm256_inserti128_si256(pr1, _mm_unpacklo_epi64(t2, u2), 1);
+
+ __m256i rr1 = _mm256_castsi128_si256(_mm_unpackhi_epi64(r0, s0));
+ __m256i rr2 = _mm256_inserti128_si256(rr1, _mm_unpackhi_epi64(t0, u0), 1);
+ return _mm256_xor_si256(pr2, _mm256_shuffle_epi8(reducer2, rr2));
+ }
+
+//
+ inline
+ __m128i _gf2ext64_mul_hi_sse(__m128i a0, __m128i b0)
+ {
+ __m128i c0 = _mm_clmulepi64_si128(a0, b0, 1);
+ __m128i c3 = _gf2ext64_reduce_sse(c0);
+ return c3;
+ }
+
+ inline
+ __m128i _gf2ext64_mul_2x1_sse(__m128i a0a1, __m128i b0)
+ {
+ __m128i c0 = _mm_clmulepi64_si128(a0a1, b0, 0);
+ __m128i c1 = _mm_clmulepi64_si128(a0a1, b0, 1);
+ __m128i c3 = _gf2ext64_reduce_x2_sse(c0, c1);
+ return c3;
+ }
+
+ inline
+ __m256i _gf2ext64_mul_4x1_avx2(__m256i a, __m128i b0)
+ {
+ __m128i al = _mm256_castsi256_si128(a);
+ __m128i c0 = _mm_clmulepi64_si128(al, b0, 0);
+ __m128i c1 = _mm_clmulepi64_si128(al, b0, 1);
+ __m128i ah = _mm256_extracti128_si256(a, 1);
+ __m128i c2 = _mm_clmulepi64_si128(ah, b0, 0);
+ __m128i c3 = _mm_clmulepi64_si128(ah, b0, 1);
+
+ return _gf2ext64_reduce_x4_avx2(c0, c1, c2, c3);
+ }
+
+
+ inline
+ __m256i _gf2ext64_mul_4x4_avx2(__m256i a, __m256i b)
+ {
+ __m128i al = _mm256_castsi256_si128(a);
+ __m128i bl = _mm256_castsi256_si128(b);
+ __m128i c0 = _mm_clmulepi64_si128(al, bl, 0);
+ __m128i c1 = _mm_clmulepi64_si128(al, bl, 0x11);
+ __m128i ah = _mm256_extracti128_si256(a, 1);
+ __m128i bh = _mm256_extracti128_si256(b, 1);
+ __m128i c2 = _mm_clmulepi64_si128(ah, bh, 0);
+ __m128i c3 = _mm_clmulepi64_si128(ah, bh, 0x11);
+
+ return _gf2ext64_reduce_x4_avx2(c0, c1, c2, c3);
+ }
+
+
+ inline
+ void gf2ext64_mul_4x4_avx2(uint8_t* c, const uint8_t* a, const uint8_t* b)
+ {
+ __m256i as = _mm256_load_si256((__m256i const*)a);
+ __m256i bs = _mm256_load_si256((__m256i const*)b);
+ __m256i cs = _gf2ext64_mul_4x4_avx2(as, bs);
+
+ _mm256_store_si256((__m256i*) c, cs);
+ }
+
+
+
+//
+
+ /////////////////////////////////////////////
+
+
+ /// X^128 + X^7 + X^2 + X + 1
+ /// 0x 8 7
+ alignas(32) const uint64_t _gf2ext128_reducer[2] = { 0x87ULL,0x0ULL };
+
+ //USED;
+ inline
+ __m128i _gf2ext128_reduce_sse(__m128i x0, __m128i x128)
+ {
+ __m128i reducer = _mm_load_si128((__m128i const*)_gf2ext128_reducer);
+ //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
+ __m128i x64 = _mm_clmulepi64_si128(x128, reducer, 1); /// 0_32 , xx2_32 , xx1 , xx0
+ x128 = _mm_xor_si128(x128, _mm_shuffle_epi32(x64, 0xfe)); // 0,0,0,xx2 ; 0xfe --> 3,3,3,2
+ x0 = _mm_xor_si128(x0, _mm_shuffle_epi32(x64, 0x4f)); // xx1 , xx0 , 0 , 0 ; 0x4f --> 1,0,3,3 --> xx1,xx0,0,0
+ x0 = _mm_xor_si128(x0, _mm_clmulepi64_si128(x128, reducer, 0));
+ return x0;
+ }
+
+
+#define _MUL_128_KARATSUBA( c0,c1,a0,b0 ) \
+do {\
+ c0 = _mm_clmulepi64_si128( a0,b0 , 0x00 ); \
+ c1 = _mm_clmulepi64_si128( a0,b0 , 0x11 ); \
+ __m128i _tt0 = _mm_xor_si128(a0, _mm_srli_si128(a0,8)); \
+ __m128i _tt1 = _mm_xor_si128(b0,_mm_srli_si128(b0,8)); \
+ __m128i _tt2 = _mm_xor_si128(_mm_xor_si128(_mm_clmulepi64_si128( _tt0, _tt1 , 0 ),c0),c1); \
+ c0 = _mm_xor_si128(c0, _mm_slli_si128( _tt2 , 8 )); \
+ c1 = _mm_xor_si128(c1,_mm_srli_si128( _tt2 , 8 )); \
+} while(0)
+
+
+ //USED;
+ inline
+ void gf2ext128_mul_sse(uint8_t* c, const uint8_t* a, const uint8_t* b)
+ {
+ __m128i a0 = _mm_load_si128((__m128i const*)a);
+ __m128i b0 = _mm_load_si128((__m128i const*)b);
+ __m128i c0, c128;
+ _MUL_128_KARATSUBA(c0, c128, a0, b0);
+
+ __m128i c3 = _gf2ext128_reduce_sse(c0, c128);
+ //__m128i c3 = _gf_aesgcm_reduce_sse( c0 , c128 );
+ _mm_store_si128((__m128i*) c, c3);
+ }
+
+
+ inline
+ __m128i _gf2ext128_mul_sse(__m128i a0, __m128i b0)
+ {
+ __m128i c0, c128;
+ _MUL_128_KARATSUBA(c0, c128, a0, b0);
+ __m128i c3 = _gf2ext128_reduce_sse(c0, c128);
+ return c3;
+ }
+
+
+ inline
+ __m256i _gf2ext128_mul_2x1_avx2(__m256i a0a1, __m128i b0)
+ {
+ __m128i a0 = _mm256_castsi256_si128(a0a1);
+ __m128i a1 = _mm256_extracti128_si256(a0a1, 1);
+
+ __m128i c0, c128;
+ __m128i d0, d128;
+ _MUL_128_KARATSUBA(c0, c128, a0, b0);
+ _MUL_128_KARATSUBA(d0, d128, a1, b0);
+ __m128i c3 = _gf2ext128_reduce_sse(c0, c128);
+ __m128i d3 = _gf2ext128_reduce_sse(d0, d128);
+
+ __m256i r = _mm256_castsi128_si256(c3);
+
+ return _mm256_inserti128_si256(r, d3, 1);
+ }
+
+
+
+ //////////////////////////////////////////////////////////////////////////////////////
+
+
+ //// s7 = x^64 + x^32 + x16 + x8 + x4 + x2 + x
+
+
+ alignas(32) const uint64_t _s7[2] = { 0x100010116ULL,0x1ULL };
+
+ inline
+ __m256i div_s7(__m256i a)
+ {
+ __m128i r_s7 = _mm_load_si128((__m128i const*)_s7);
+ __m128i a1 = _mm256_extracti128_si256(a, 1);
+ __m128i a0 = _mm256_castsi256_si128(a);
+
+ __m128i a1h_s7 = _mm_clmulepi64_si128(a1, r_s7, 1);
+ a1 = _mm_xor_si128(a1, _mm_srli_si128(_mm_xor_si128(a1, a1h_s7), 8));
+ a0 = _mm_xor_si128(a0, _mm_slli_si128(a1h_s7, 8));
+
+ a0 = _mm_xor_si128(a0, _mm_slli_si128(a1, 8));
+ a0 = _mm_xor_si128(a0, _mm_clmulepi64_si128(a1, r_s7, 0));
+
+ __m256i r = _mm256_castsi128_si256(a0);
+ return _mm256_inserti128_si256(r, a1, 1);
+ }
+
+
+ //USED;
+ inline
+ __m256i exp_s7(__m256i a)
+ {
+ __m128i r_s7 = _mm_load_si128((__m128i const*)_s7);
+ __m128i a1 = _mm256_extracti128_si256(a, 1);
+ __m128i a0 = _mm256_castsi256_si128(a);
+
+ a0 = _mm_xor_si128(a0, _mm_clmulepi64_si128(a1, r_s7, 0));
+ a0 = _mm_xor_si128(a0, _mm_slli_si128(a1, 8));
+ __m128i a1h_s7 = _mm_clmulepi64_si128(a1, r_s7, 1);
+ a0 = _mm_xor_si128(a0, _mm_slli_si128(a1h_s7, 8));
+ a1 = _mm_xor_si128(a1, _mm_srli_si128(_mm_xor_si128(a1, a1h_s7), 8));
+
+ __m256i r = _mm256_castsi128_si256(a0);
+ return _mm256_inserti128_si256(r, a1, 1);
+ }
+
+}
+
diff --git a/ska.h b/bitpolymul/ska.h
similarity index 84%
rename from ska.h
rename to bitpolymul/ska.h
index e836fc0..c1f9796 100644
--- a/ska.h
+++ b/bitpolymul/ska.h
@@ -1,3 +1,4 @@
+#pragma once
/*
Copyright (C) 2017 Ming-Shing Chen
@@ -17,11 +18,8 @@ You should have received a copy of the GNU Lesser General Public License
along with BitPolyMul. If not, see .
*/
-#ifndef _SKA_H_
-#define _SKA_H_
-
-static inline
-unsigned get_s_k_a_cantor( unsigned k , unsigned a ) { return (a>>k); }
-
-#endif
+namespace bpm {
+ inline
+ unsigned get_s_k_a_cantor(unsigned k, unsigned a) { return (a >> k); }
+}
diff --git a/bitpolymul/transpose.h b/bitpolymul/transpose.h
new file mode 100644
index 0000000..1f6322c
--- /dev/null
+++ b/bitpolymul/transpose.h
@@ -0,0 +1,397 @@
+#pragma once
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+
+#include
+#include
+#include "bpmDefines.h"
+#include "transpose_bit.h"
+
+namespace bpm {
+
+ alignas(32) const uint8_t _tr_4x4[32] = { 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 ,0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 };
+
+ //USED;
+ inline
+ void tr_avx2_4x4_b8(uint8_t* _r, const uint8_t* a) {
+
+ __m256i r0 = _mm256_load_si256((__m256i*) a);
+ __m256i r1 = _mm256_load_si256((__m256i*) (a + 32));
+ __m256i r2 = _mm256_load_si256((__m256i*) (a + 64));
+ __m256i r3 = _mm256_load_si256((__m256i*) (a + 96));
+
+ __m256i t0 = _mm256_shuffle_epi8(r0, *(__m256i*)_tr_4x4); // 00,01,02,03
+ __m256i t1 = _mm256_shuffle_epi8(r1, *(__m256i*)_tr_4x4); // 10,11,12,13
+ __m256i t2 = _mm256_shuffle_epi8(r2, *(__m256i*)_tr_4x4); // 20,21,22,23
+ __m256i t3 = _mm256_shuffle_epi8(r3, *(__m256i*)_tr_4x4); // 30,31,32,33
+
+ __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11
+ __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13
+ __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31
+ __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33
+
+ __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30
+ __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31
+ __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32
+ __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33
+
+ __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4);
+ __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4);
+ __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4);
+ __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4);
+
+ _mm256_store_si256((__m256i*) _r, s0);
+ _mm256_store_si256((__m256i*) (_r + 32), s1);
+ _mm256_store_si256((__m256i*) (_r + 64), s2);
+ _mm256_store_si256((__m256i*) (_r + 96), s3);
+ }
+
+
+
+ //USED;
+ inline
+ void tr_16x16_b2_from_4x4_b8_1_4(uint8_t* r, const uint8_t* a) {
+
+ __m256i a0 = _mm256_load_si256((__m256i*) a); // 00,04,08,0c
+ __m256i a4 = _mm256_load_si256((__m256i*) (a + 32 * 4)); // 10,14,18,1c
+ __m256i a8 = _mm256_load_si256((__m256i*) (a + 32 * 8)); // 20,24,28,2c
+ __m256i ac = _mm256_load_si256((__m256i*) (a + 32 * 12)); // 30,34,38,3c
+
+ __m256i a04l = _mm256_unpacklo_epi32(a0, a4); // 00,10,04,14
+ __m256i a04h = _mm256_unpackhi_epi32(a0, a4); // 08,18,0c,1c
+ __m256i a8cl = _mm256_unpacklo_epi32(a8, ac); // 20,30,24,34
+ __m256i a8ch = _mm256_unpackhi_epi32(a8, ac); // 28,38,2c,3c
+
+ __m256i b0 = _mm256_unpacklo_epi64(a04l, a8cl); // 00,10,20,30
+ __m256i b4 = _mm256_unpackhi_epi64(a04l, a8cl); // 04,14,24,34
+ __m256i b8 = _mm256_unpacklo_epi64(a04h, a8ch); // 08,18,28,38
+ __m256i bc = _mm256_unpackhi_epi64(a04h, a8ch); // 0c,1c,2c,3c
+
+ _mm256_store_si256((__m256i*) (r + 32 * 0), b0);
+ _mm256_store_si256((__m256i*) (r + 32 * 4), b4);
+ _mm256_store_si256((__m256i*) (r + 32 * 8), b8);
+ _mm256_store_si256((__m256i*) (r + 32 * 12), bc);
+ }
+
+
+ //USED;
+ inline
+ void tr_16x16_b2_avx2(uint8_t* r, const uint8_t* a) {
+ alignas(32) uint8_t temp[32 * 16];
+ for (unsigned i = 0; i < 4; i++) tr_avx2_4x4_b8(temp + i * 32 * 4, a + i * 32 * 4);
+ tr_16x16_b2_from_4x4_b8_1_4(r, temp);
+ tr_16x16_b2_from_4x4_b8_1_4(r + 32, temp + 32);
+ tr_16x16_b2_from_4x4_b8_1_4(r + 32 * 2, temp + 32 * 2);
+ tr_16x16_b2_from_4x4_b8_1_4(r + 32 * 3, temp + 32 * 3);
+ }
+
+ //USED;
+ inline
+ void tr_8x8_b4_avx2(uint8_t* _r, const uint8_t* a, const uint64_t mem_len) {
+ /// code of 4x4_b8
+ __m256i r0 = _mm256_load_si256((__m256i*) a);
+ __m256i r1 = _mm256_load_si256((__m256i*) (a + mem_len * 1));
+ __m256i r2 = _mm256_load_si256((__m256i*) (a + mem_len * 2));
+ __m256i r3 = _mm256_load_si256((__m256i*) (a + mem_len * 3));
+
+ __m256i t0 = _mm256_shuffle_epi8(r0, *(__m256i*)_tr_4x4); // 00,01,02,03
+ __m256i t1 = _mm256_shuffle_epi8(r1, *(__m256i*)_tr_4x4); // 10,11,12,13
+ __m256i t2 = _mm256_shuffle_epi8(r2, *(__m256i*)_tr_4x4); // 20,21,22,23
+ __m256i t3 = _mm256_shuffle_epi8(r3, *(__m256i*)_tr_4x4); // 30,31,32,33
+
+ __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11
+ __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13
+ __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31
+ __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33
+
+ __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30
+ __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31
+ __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32
+ __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33
+
+ __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4);
+ __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4);
+ __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4);
+ __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4);
+
+ /// repeat 4x4_b8
+ r0 = _mm256_load_si256((__m256i*) (a + mem_len * 4));
+ r1 = _mm256_load_si256((__m256i*) (a + mem_len * 5));
+ r2 = _mm256_load_si256((__m256i*) (a + mem_len * 6));
+ r3 = _mm256_load_si256((__m256i*) (a + mem_len * 7));
+
+ t0 = _mm256_shuffle_epi8(r0, *(__m256i*)_tr_4x4); // 00,01,02,03
+ t1 = _mm256_shuffle_epi8(r1, *(__m256i*)_tr_4x4); // 10,11,12,13
+ t2 = _mm256_shuffle_epi8(r2, *(__m256i*)_tr_4x4); // 20,21,22,23
+ t3 = _mm256_shuffle_epi8(r3, *(__m256i*)_tr_4x4); // 30,31,32,33
+
+ t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11
+ t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13
+ t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31
+ t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33
+
+ r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30
+ r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31
+ r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32
+ r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33
+
+ __m256i s4 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4);
+ __m256i s5 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4);
+ __m256i s6 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4);
+ __m256i s7 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4);
+
+ /// transpose s0,..., s7
+ t0 = _mm256_unpacklo_epi32(s0, s4); // s0_0 , s4_0 , s0_1 , s4_1
+ t1 = _mm256_unpackhi_epi32(s0, s4); // s0_2 , s4_2 , s0_3 , s4_3
+ s0 = _mm256_unpacklo_epi64(t0, t1); // s0_0 , s4_0 , s0_2 , s4_2
+ s4 = _mm256_unpackhi_epi64(t0, t1); // s0_1 , s4_1 , s0_3 , s4_3
+
+ t2 = _mm256_unpacklo_epi32(s1, s5);
+ t3 = _mm256_unpackhi_epi32(s1, s5);
+ s1 = _mm256_unpacklo_epi64(t2, t3);
+ s5 = _mm256_unpackhi_epi64(t2, t3);
+
+ t0 = _mm256_unpacklo_epi32(s2, s6);
+ t1 = _mm256_unpackhi_epi32(s2, s6);
+ s2 = _mm256_unpacklo_epi64(t0, t1);
+ s6 = _mm256_unpackhi_epi64(t0, t1);
+
+ t2 = _mm256_unpacklo_epi32(s3, s7);
+ t3 = _mm256_unpackhi_epi32(s3, s7);
+ s3 = _mm256_unpacklo_epi64(t2, t3);
+ s7 = _mm256_unpackhi_epi64(t2, t3);
+
+ _mm256_store_si256((__m256i*) _r, s0);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 1), s1);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 2), s2);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 3), s3);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 4), s4);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 5), s5);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 6), s6);
+ _mm256_store_si256((__m256i*) (_r + mem_len * 7), s7);
+ }
+
+ //USED;
+ inline
+ void transpose_8x8_b4_avx2(uint8_t* _r, const uint8_t* a) {
+#if 0
+ tr_8x8_b4_avx2(_r, a, 32);
+#else
+ __m256i a0 = _mm256_load_si256((__m256i*) a);
+ __m256i a1 = _mm256_load_si256((__m256i*) (a + 32 * 1));
+ __m256i a2 = _mm256_load_si256((__m256i*) (a + 32 * 2));
+ __m256i a3 = _mm256_load_si256((__m256i*) (a + 32 * 3));
+ __m256i a4 = _mm256_load_si256((__m256i*) (a + 32 * 4));
+ __m256i a5 = _mm256_load_si256((__m256i*) (a + 32 * 5));
+ __m256i a6 = _mm256_load_si256((__m256i*) (a + 32 * 6));
+ __m256i a7 = _mm256_load_si256((__m256i*) (a + 32 * 7));
+
+ __m256i t0, t1, t2, t3;
+ t0 = _mm256_unpacklo_epi32(a0, a4);
+ t1 = _mm256_unpackhi_epi32(a0, a4);
+ a0 = _mm256_unpacklo_epi64(t0, t1);
+ a4 = _mm256_unpackhi_epi64(t0, t1);
+
+ t2 = _mm256_unpacklo_epi32(a1, a5);
+ t3 = _mm256_unpackhi_epi32(a1, a5);
+ a1 = _mm256_unpacklo_epi64(t2, t3);
+ a5 = _mm256_unpackhi_epi64(t2, t3);
+
+ t0 = _mm256_unpacklo_epi32(a2, a6);
+ t1 = _mm256_unpackhi_epi32(a2, a6);
+ a2 = _mm256_unpacklo_epi64(t0, t1);
+ a6 = _mm256_unpackhi_epi64(t0, t1);
+
+ t2 = _mm256_unpacklo_epi32(a3, a7);
+ t3 = _mm256_unpackhi_epi32(a3, a7);
+ a3 = _mm256_unpacklo_epi64(t2, t3);
+ a7 = _mm256_unpackhi_epi64(t2, t3);
+
+ /// code of 4x4_b8
+ t0 = _mm256_shuffle_epi8(a0, *(__m256i*)_tr_4x4); // 00,01,02,03
+ t1 = _mm256_shuffle_epi8(a1, *(__m256i*)_tr_4x4); // 10,11,12,13
+ t2 = _mm256_shuffle_epi8(a2, *(__m256i*)_tr_4x4); // 20,21,22,23
+ t3 = _mm256_shuffle_epi8(a3, *(__m256i*)_tr_4x4); // 30,31,32,33
+
+ __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11
+ __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13
+ __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31
+ __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33
+
+ __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30
+ __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31
+ __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32
+ __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33
+
+ __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4);
+ __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4);
+ __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4);
+ __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4);
+
+ /// repeat 4x4_b8
+ t0 = _mm256_shuffle_epi8(a4, *(__m256i*)_tr_4x4); // 00,01,02,03
+ t1 = _mm256_shuffle_epi8(a5, *(__m256i*)_tr_4x4); // 10,11,12,13
+ t2 = _mm256_shuffle_epi8(a6, *(__m256i*)_tr_4x4); // 20,21,22,23
+ t3 = _mm256_shuffle_epi8(a7, *(__m256i*)_tr_4x4); // 30,31,32,33
+
+ t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11
+ t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13
+ t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31
+ t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33
+
+ r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30
+ r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31
+ r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32
+ r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33
+
+ __m256i s4 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4);
+ __m256i s5 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4);
+ __m256i s6 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4);
+ __m256i s7 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4);
+
+ _mm256_store_si256((__m256i*) _r, s0);
+ _mm256_store_si256((__m256i*) (_r + 32 * 1), s1);
+ _mm256_store_si256((__m256i*) (_r + 32 * 2), s2);
+ _mm256_store_si256((__m256i*) (_r + 32 * 3), s3);
+ _mm256_store_si256((__m256i*) (_r + 32 * 4), s4);
+ _mm256_store_si256((__m256i*) (_r + 32 * 5), s5);
+ _mm256_store_si256((__m256i*) (_r + 32 * 6), s6);
+ _mm256_store_si256((__m256i*) (_r + 32 * 7), s7);
+#endif
+ }
+
+
+
+ inline
+ void transpose_8x8_h4zero_b4_avx2(uint8_t* _r, const uint8_t* a) {
+ __m256i a0 = _mm256_load_si256((__m256i*) a);
+ __m256i a1 = _mm256_load_si256((__m256i*) (a + 32 * 1));
+ __m256i a2 = _mm256_load_si256((__m256i*) (a + 32 * 2));
+ __m256i a3 = _mm256_load_si256((__m256i*) (a + 32 * 3));
+ __m256i a4 = _mm256_load_si256((__m256i*) (a + 32 * 4));
+ __m256i a5 = _mm256_load_si256((__m256i*) (a + 32 * 5));
+ __m256i a6 = _mm256_load_si256((__m256i*) (a + 32 * 6));
+ __m256i a7 = _mm256_load_si256((__m256i*) (a + 32 * 7));
+
+ __m256i t0, t1, t2, t3;
+ t0 = _mm256_unpacklo_epi32(a0, a4);
+ t1 = _mm256_unpackhi_epi32(a0, a4);
+ a0 = _mm256_unpacklo_epi64(t0, t1);
+
+ t2 = _mm256_unpacklo_epi32(a1, a5);
+ t3 = _mm256_unpackhi_epi32(a1, a5);
+ a1 = _mm256_unpacklo_epi64(t2, t3);
+
+ t0 = _mm256_unpacklo_epi32(a2, a6);
+ t1 = _mm256_unpackhi_epi32(a2, a6);
+ a2 = _mm256_unpacklo_epi64(t0, t1);
+
+ t2 = _mm256_unpacklo_epi32(a3, a7);
+ t3 = _mm256_unpackhi_epi32(a3, a7);
+ a3 = _mm256_unpacklo_epi64(t2, t3);
+
+ /// code of 4x4_b8
+ t0 = _mm256_shuffle_epi8(a0, *(__m256i*)_tr_4x4); // 00,01,02,03
+ t1 = _mm256_shuffle_epi8(a1, *(__m256i*)_tr_4x4); // 10,11,12,13
+ t2 = _mm256_shuffle_epi8(a2, *(__m256i*)_tr_4x4); // 20,21,22,23
+ t3 = _mm256_shuffle_epi8(a3, *(__m256i*)_tr_4x4); // 30,31,32,33
+
+ __m256i t01lo = _mm256_unpacklo_epi32(t0, t1); // 00,10,01,11
+ __m256i t01hi = _mm256_unpackhi_epi32(t0, t1); // 02,12,03,13
+ __m256i t23lo = _mm256_unpacklo_epi32(t2, t3); // 20,30,21,31
+ __m256i t23hi = _mm256_unpackhi_epi32(t2, t3); // 22,32,23,33
+
+ __m256i r01lo = _mm256_unpacklo_epi64(t01lo, t23lo); // 00,10,20,30
+ __m256i r01hi = _mm256_unpackhi_epi64(t01lo, t23lo); // 01,11,21,31
+ __m256i r23lo = _mm256_unpacklo_epi64(t01hi, t23hi); // 02,12,22,32
+ __m256i r23hi = _mm256_unpackhi_epi64(t01hi, t23hi); // 03,13,23,33
+
+ __m256i s0 = _mm256_shuffle_epi8(r01lo, *(__m256i*)_tr_4x4);
+ __m256i s1 = _mm256_shuffle_epi8(r01hi, *(__m256i*)_tr_4x4);
+ __m256i s2 = _mm256_shuffle_epi8(r23lo, *(__m256i*)_tr_4x4);
+ __m256i s3 = _mm256_shuffle_epi8(r23hi, *(__m256i*)_tr_4x4);
+
+ _mm256_store_si256((__m256i*) _r, s0);
+ _mm256_store_si256((__m256i*) (_r + 32 * 1), s1);
+ _mm256_store_si256((__m256i*) (_r + 32 * 2), s2);
+ _mm256_store_si256((__m256i*) (_r + 32 * 3), s3);
+
+ }
+
+
+
+
+
+
+
+ //USED;
+ inline
+ void tr_bit_8x8_b32_avx2(uint8_t* _r, const uint8_t* a) {
+ for (unsigned i = 0; i < 8; i++) {
+ tr_bit_8x8_b4_avx(_r + (32 * i), a + (32 * i));
+ }
+
+ tr_8x8_b4_avx2(_r, _r, 32);
+
+ for (unsigned i = 0; i < 8; i++) {
+ tr_bit_8x8_b4_avx(_r + (32 * i), _r + (32 * i));
+ }
+ }
+
+
+
+ //USED;
+ inline
+ void tr_bit_64x64_b4_avx2(uint8_t* _r, const uint8_t* a) {
+ for (unsigned i = 0; i < 8; i++) {
+ tr_bit_8x8_b32_avx2(_r + (32 * 8 * i), a + (32 * 8 * i));
+ }
+
+ for (unsigned i = 0; i < 8; i++) {
+ tr_8x8_b4_avx2(_r + 32 * i, _r + 32 * i, 32 * 8);
+ }
+ }
+
+
+ //USED;
+ inline
+ void tr_bit_128x128_b2_avx2(uint8_t* _r, const uint8_t* a) {
+ tr_bit_64x64_b4_avx2(_r, a);
+ tr_bit_64x64_b4_avx2(_r + 64 * 32, a + 64 * 32);
+
+ for (unsigned i = 0; i < 64; i++) {
+ __m256i m00_m01 = _mm256_load_si256((__m256i*) (_r + 32 * i)); // 00 , 01
+ __m256i m10_m11 = _mm256_load_si256((__m256i*) (_r + 32 * i + 32 * 64)); // 10 , 11
+ __m256i t0 = _mm256_unpacklo_epi64(m00_m01, m10_m11); // 00 , 10
+ __m256i t1 = _mm256_unpackhi_epi64(m00_m01, m10_m11); // 01 , 11
+ _mm256_store_si256((__m256i*) (_r + 32 * i), t0);
+ _mm256_store_si256((__m256i*) (_r + 32 * i + 32 * 64), t1);
+
+ }
+ }
+
+
+
+
+
+
+}
+
diff --git a/bitpolymul/transpose_bit.h b/bitpolymul/transpose_bit.h
new file mode 100644
index 0000000..db6e0b3
--- /dev/null
+++ b/bitpolymul/transpose_bit.h
@@ -0,0 +1,45 @@
+#pragma once
+/*
+
+Code is borrowed from HOEVEN, LARRIEU, and LECERF.
+
+*/
+
+#include
+#include
+#include "bpmDefines.h"
+
+namespace bpm {
+
+ alignas(32) const uint64_t _tr_bit_mask_4[4] = { 0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL };
+ alignas(32) const uint64_t _tr_bit_mask_2[4] = { 0x0000cccc0000ccccULL,0x0000cccc0000ccccULL,0x0000cccc0000ccccULL,0x0000cccc0000ccccULL };
+ alignas(32) const uint64_t _tr_bit_mask_1[4] = { 0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL };
+
+
+ inline
+ __m256i tr_bit_8x8_b4_ymmx1(__m256i n) {
+ __m256i a;
+
+ a = and256(xor256(_mm256_srli_epi64(n, 28), n), (*(__m256i*)_tr_bit_mask_4)); n = xor256(n, a);
+ a = _mm256_slli_epi64(a, 28); n = xor256(n, a);
+ a = and256(xor256(_mm256_srli_epi64(n, 14), n), (*(__m256i*)_tr_bit_mask_2)); n = xor256(n, a);
+ a = _mm256_slli_epi64(a, 14); n = xor256(n, a);
+ a = and256(xor256(_mm256_srli_epi64(n, 7), n), (*(__m256i*)_tr_bit_mask_1)); n = xor256(n, a);
+ a = _mm256_slli_epi64(a, 7); n = xor256(n, a);
+
+ return n;
+ }
+
+
+ //USED;
+ inline
+ void tr_bit_8x8_b4_avx(uint8_t* _r, const uint8_t* m) {
+
+ __m256i n = _mm256_load_si256((__m256i*) m);
+ __m256i r = tr_bit_8x8_b4_ymmx1(n);
+ _mm256_store_si256((__m256i*) _r, r);
+ }
+
+
+}
+
diff --git a/bitpolymul/trunc_btfy_tab.h b/bitpolymul/trunc_btfy_tab.h
new file mode 100644
index 0000000..f4b0e1b
--- /dev/null
+++ b/bitpolymul/trunc_btfy_tab.h
@@ -0,0 +1,1064 @@
+#pragma once
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+
+#include "stdint.h"
+
+
+
+namespace bpm {
+
+
+ alignas(32) const uint64_t beta_mul_64_bm4r_ext_8[2 * 128 * 4 * 2] = {
+ 0x8d8cadac21200100,0x9c9dbcbd30311011,0x8d8cadac21200100,0x9c9dbcbd30311011,
+ 0xfe769810ee668800,0x8008e66e9018f67e,0xfe769810ee668800,0x8008e66e9018f67e,
+ 0xb2b25454e6e60000,0xa2a24444f6f61010,0xb2b25454e6e60000,0xa2a24444f6f61010,
+ 0xbf50cf209f70ef00,0xdc33ac43fc138c63,0xbf50cf209f70ef00,0xdc33ac43fc138c63,
+ 0xe3e3707093930000,0xc7c75454b7b72424,0xe3e3707093930000,0xc7c75454b7b72424,
+ 0xc5f4a8995c6d3100,0xaa9bc7f633025e6f,0xc5f4a8995c6d3100,0xaa9bc7f633025e6f,
+ 0xc7c7d7d710100000,0x3c3c2c2cebebfbfb,0xc7c7d7d710100000,0x3c3c2c2cebebfbfb,
+ 0x5f51ddd38c820e00,0xf0fe727c232da1af,0x5f51ddd38c820e00,0xf0fe727c232da1af,
+ 0x8080949414140000,0x8181959515150101,0x8080949414140000,0x8181959515150101,
+ 0x4de4d37a379ea900,0x57fec9602d84b31a,0x4de4d37a379ea900,0x57fec9602d84b31a,
+ 0x5d5d141449490000,0xa3a3eaeab7b7fefe,0x5d5d141449490000,0xa3a3eaeab7b7fefe,
+ 0xd357119546c28400,0xe8acc489b1f59dd,0xd357119546c28400,0xe8acc489b1f59dd,
+ 0xe9e91a1af3f30000,0x303f0f01919eaea,0xe9e91a1af3f30000,0x303f0f01919eaea,
+ 0xf0646bff0f9b9400,0xdc4847d323b7b82c,0xf0646bff0f9b9400,0xdc4847d323b7b82c,
+ 0x5050777727270000,0x5d5d7a7a2a2a0d0d,0x5050777727270000,0x5d5d7a7a2a2a0d0d,
+ 0x7e5aeecab4902400,0xffdb6f4b3511a581,0x7e5aeecab4902400,0xffdb6f4b3511a581,
+ 0xede1333fd2de0c00,0xa6aa78749995474b,0xede1333fd2de0c00,0xa6aa78749995474b,
+ 0x7688be4036c8fe00,0xe41a2cd2a45a6c92,0x7688be4036c8fe00,0xe41a2cd2a45a6c92,
+ 0x7a583a1862402200,0x1b395b7903214361,0x7a583a1862402200,0x1b395b7903214361,
+ 0xea90a7dd374d7a00,0x6b11265cb6ccfb81,0xea90a7dd374d7a00,0x6b11265cb6ccfb81,
+ 0x5273d9f8aa8b2100,0xfbda7051032288a9,0x5273d9f8aa8b2100,0xfbda7051032288a9,
+ 0xf534d819ec2dc100,0x46876baa5f9e72b3,0xf534d819ec2dc100,0x46876baa5f9e72b3,
+ 0xd4c3c3d400171700,0xd0c7c7d004131304,0xd4c3c3d400171700,0xd0c7c7d004131304,
+ 0xf9d6230cf5da2f00,0x827d2fd042bdef1,0xf9d6230cf5da2f00,0x827d2fd042bdef1,
+ 0x4ca91cf9b550e500,0x39dc698cc0259075,0x4ca91cf9b550e500,0x39dc698cc0259075,
+ 0xc2a57710d2b56700,0x661b3d41671a3c4,0xc2a57710d2b56700,0x661b3d41671a3c4,
+ 0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81,0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81,
+ 0x7bf68c017af78d00,0x489f37e0588f27f,0x7bf68c017af78d00,0x489f37e0588f27f,
+ 0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a,0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a,
+ 0xbf58709728cfe700,0x1ef9d136896e46a1,0xbf58709728cfe700,0x1ef9d136896e46a1,
+ 0x8c5ded3cb061d100,0x9140f021ad7ccc1d,0x8c5ded3cb061d100,0x9140f021ad7ccc1d,
+ 0x51eaeb5001babb00,0xa31819a2f34849f2,0x51eaeb5001babb00,0xa31819a2f34849f2,
+ 0x6e54261c72483a00,0x90aad8e28cb6c4fe,0x6e54261c72483a00,0x90aad8e28cb6c4fe,
+ 0xd4f0e4c41034200,0x490b4a0805470644,0xd4f0e4c41034200,0x490b4a0805470644,
+ 0xac29d653ff7a8500,0xa520df5af6738c09,0xac29d653ff7a8500,0xa520df5af6738c09,
+ 0x3296a90d3f9ba400,0x2581be1a288cb317,0x3296a90d3f9ba400,0x2581be1a288cb317,
+ 0x61f6b02746d19700,0xc4531582e37432a5,0x61f6b02746d19700,0xc4531582e37432a5,
+ 0x74ddd47d09a0a900,0x5aca50c78d1d871,0x74ddd47d09a0a900,0x5aca50c78d1d871,
+ 0xb288566cdee43a00,0x7e449aa01228f6cc,0xb288566cdee43a00,0x7e449aa01228f6cc,
+ 0xf9d7cae41d332e00,0xc6e8f5db220c113f,0xf9d7cae41d332e00,0xc6e8f5db220c113f,
+ 0xc088d29a5a124800,0x4b035911d199c38b,0xc088d29a5a124800,0x4b035911d199c38b,
+ 0xd4220bfd29dff600,0x18eec731e5133acc,0xd4220bfd29dff600,0x18eec731e5133acc,
+ 0x3417715266452300,0xeecdab88bc9ff9da,0x3417715266452300,0xeecdab88bc9ff9da,
+ 0xbc74d61ea26ac800,0x3cb69a11dd577bf,0xbc74d61ea26ac800,0x3cb69a11dd577bf,
+ 0xbe30149a24aa8e00,0xba34109e20ae8a04,0xbe30149a24aa8e00,0xba34109e20ae8a04,
+ 0x7157c3e594b22600,0xcaec785e2f099dbb,0x7157c3e594b22600,0xcaec785e2f099dbb,
+ 0xfc268d57ab71da00,0xf12b805aa67cd70d,0xfc268d57ab71da00,0xf12b805aa67cd70d,
+ 0x22a3b8391b9a8100,0xbd3c27a684051e9f,0x22a3b8391b9a8100,0xbd3c27a684051e9f,
+ 0x8bfc1265ee997700,0x4235dbac2750bec9,0x8bfc1265ee997700,0x4235dbac2750bec9,
+ 0xfb2c4a9d66b1d700,0xb36402d52ef99f48,0xfb2c4a9d66b1d700,0xb36402d52ef99f48,
+ 0x2c30a8b498841c00,0xb1ad35290519819d,0x2c30a8b498841c00,0xb1ad35290519819d,
+ 0xc41378af6bbcd700,0xda0d66b175a2c91e,0xc41378af6bbcd700,0xda0d66b175a2c91e,
+ 0x52535b5a08090100,0xf3f2fafba9a8a0a1,0x52535b5a08090100,0xf3f2fafba9a8a0a1,
+ 0x82519142c013d300,0x27f434e765b676a5,0x82519142c013d300,0x27f434e765b676a5,
+ 0x5c2094e8b4c87c00,0xb6ca7e025e2296ea,0x5c2094e8b4c87c00,0xb6ca7e025e2296ea,
+ 0x4848fefeb6b60000,0xaaaa1c1c5454e2e2,0x4848fefeb6b60000,0xaaaa1c1c5454e2e2,
+ 0x4f142e753a615b00,0xa0fbc19ad58eb4ef,0x4f142e753a615b00,0xa0fbc19ad58eb4ef,
+ 0x750c7801740d7900,0x423b4f36433a4e37,0x750c7801740d7900,0x423b4f36433a4e37,
+ 0x36da26cafc10ec00,0x22ce32dee804f814,0x36da26cafc10ec00,0x22ce32dee804f814,
+ 0x61bac31879a2db00,0x419ae3385982fb20,0x61bac31879a2db00,0x419ae3385982fb20,
+ 0x8eb70a33bd843900,0xe6df625bd5ec5168,0x8eb70a33bd843900,0xe6df625bd5ec5168,
+ 0xc6b9fa85433c7f00,0xa1de9de2245b1867,0xc6b9fa85433c7f00,0xa1de9de2245b1867,
+ 0xf248813bc973ba00,0xb70dc47e8c36ff45,0xf248813bc973ba00,0xb70dc47e8c36ff45,
+ 0xb2c5f38436417700,0xf285b3c476013740,0xb2c5f38436417700,0xf285b3c476013740,
+ 0x5898bb7b23e3c000,0x4c8caf6f37f7d414,0x5898bb7b23e3c000,0x4c8caf6f37f7d414,
+ 0x76b31edbad68c500,0x9653fe3b4d8825e0,0x76b31edbad68c500,0x9653fe3b4d8825e0,
+ 0xd064ac18c87cb400,0x52e62e9a4afe3682,0xd064ac18c87cb400,0x52e62e9a4afe3682,
+ 0x519664a3f235c700,0xa562905706c133f4,0x519664a3f235c700,0xa562905706c133f4,
+ 0x7b64322d56491f00,0x8d92c4dba0bfe9f6,0x7b64322d56491f00,0x8d92c4dba0bfe9f6,
+ 0x4f02723f703d4d00,0xcd80f0bdf2bfcf82,0x4f02723f703d4d00,0xcd80f0bdf2bfcf82,
+ 0xf139cd05f43cc800,0x76be4a8273bb4f87,0xf139cd05f43cc800,0x76be4a8273bb4f87,
+ 0xecb06539d5895c00,0x5c89d53965b0ec,0xecb06539d5895c00,0x5c89d53965b0ec,
+ 0xa63959c660ff9f00,0x50cfaf30960969f6,0xa63959c660ff9f00,0x50cfaf30960969f6,
+ 0x7d1e82e19cff6300,0xd3b02c4f3251cdae,0x7d1e82e19cff6300,0xd3b02c4f3251cdae,
+ 0xab28bd3e95168300,0x86059013b83bae2d,0xab28bd3e95168300,0x86059013b83bae2d,
+ 0x6109f39bfa926800,0x325aa0c8a9c13b53,0x6109f39bfa926800,0x325aa0c8a9c13b53,
+ 0xf6864a3accbc7000,0xc6b67a0afc8c4030,0xf6864a3accbc7000,0xc6b67a0afc8c4030,
+ 0xa9690bcb62a2c000,0xd61674b41dddbf7f,0xa9690bcb62a2c000,0xd61674b41dddbf7f,
+ 0xe8b25f05edb75a00,0x7c26cb917923ce94,0xe8b25f05edb75a00,0x7c26cb917923ce94,
+ 0x67e5da583fbd8200,0xcc4e71f3941629ab,0x67e5da583fbd8200,0xcc4e71f3941629ab,
+ 0x8e750df67883fb00,0x44bfc73cb24931ca,0x8e750df67883fb00,0x44bfc73cb24931ca,
+ 0xe451fc49ad18b500,0x95208d38dc69c471,0xe451fc49ad18b500,0x95208d38dc69c471,
+ 0x51a34dbfee1cf200,0x3f11fedbc4ea052,0x51a34dbfee1cf200,0x3f11fedbc4ea052,
+ 0x7dcaa21568dfb700,0xe0573f88f5422a9d,0x7dcaa21568dfb700,0xe0573f88f5422a9d,
+ 0x67d702b2d565b000,0x5beb3e8ee9598c3c,0x67d702b2d565b000,0x5beb3e8ee9598c3c,
+ 0xb428811da9359c00,0x9804ad318519b02c,0xb428811da9359c00,0x9804ad318519b02c,
+ 0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f,0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f,
+ 0x3d00734e734e3d00,0x4d70033e033e4d70,0x3d00734e734e3d00,0x4d70033e033e4d70,
+ 0xdf4c22b16efd9300,0xbe2d43d00f9cf261,0xdf4c22b16efd9300,0xbe2d43d00f9cf261,
+ 0x36e9419ea877df00,0xb768c01f29f65e81,0x36e9419ea877df00,0xb768c01f29f65e81,
+ 0xd499afe2367b4d00,0xd39ea8e5317c4a07,0xd499afe2367b4d00,0xd39ea8e5317c4a07,
+ 0xcfc9edeb24220600,0x5c5a7e78b7b19593,0xcfc9edeb24220600,0x5c5a7e78b7b19593,
+ 0xc5c3dfd91c1a0600,0x9a9c80864345595f,0xc5c3dfd91c1a0600,0x9a9c80864345595f,
+ 0x9387120695811400,0xdfcb5e4ad9cd584c,0x9387120695811400,0xdfcb5e4ad9cd584c,
+ 0xbc469d67db21fa00,0x728853a915ef34ce,0xbc469d67db21fa00,0x728853a915ef34ce,
+ 0x52c555c290079700,0x980f9f085acd5dca,0x52c555c290079700,0x980f9f085acd5dca,
+ 0xd7549f1ccb488300,0xc142890add5e9516,0xd7549f1ccb488300,0xc142890add5e9516,
+ 0x21a8d25b7af38900,0xc44d37be9f166ce5,0x21a8d25b7af38900,0xc44d37be9f166ce5,
+ 0x8bba5e6fe4d53100,0x5c6d89b83302e6d7,0x8bba5e6fe4d53100,0x5c6d89b83302e6d7,
+ 0xc565df7fba1aa000,0x9f3f8525e040fa5a,0xc565df7fba1aa000,0x9f3f8525e040fa5a,
+ 0x17c457849340d300,0x70a330e3f427b467,0x17c457849340d300,0x70a330e3f427b467,
+ 0xac286eea46c28400,0x6de9af2b870345c1,0xac286eea46c28400,0x6de9af2b870345c1,
+ 0xf96f29bf46d09600,0xbe286ef80197d147,0xf96f29bf46d09600,0xbe286ef80197d147,
+ 0xf444bb0bff4fb000,0x76c639897dcd3282,0xf444bb0bff4fb000,0x76c639897dcd3282,
+ 0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe,0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe,
+ 0x58ca9a0850c29200,0x861444d68e1c4cde,0x58ca9a0850c29200,0x861444d68e1c4cde,
+ 0x5e045208560c5a00,0x6832643e603a6c36,0x5e045208560c5a00,0x6832643e603a6c36,
+ 0xa9aac8cb62610300,0x1a197b78d1d2b0b3,0xa9aac8cb62610300,0x1a197b78d1d2b0b3,
+ 0xf87dac29d1548500,0x47c213966eeb3abf,0xf87dac29d1548500,0x47c213966eeb3abf,
+ 0x663ffea7c1985900,0xc89150096f36f7ae,0x663ffea7c1985900,0xc89150096f36f7ae,
+ 0x926e3ec250acfc00,0x897525d94bb7e71b,0x926e3ec250acfc00,0x897525d94bb7e71b,
+ 0x208f02ad8d22af00,0x369914bb9b34b916,0x208f02ad8d22af00,0x369914bb9b34b916,
+ 0x2a0b24052f0e2100,0xdffed1f0dafbd4f5,0x2a0b24052f0e2100,0xdffed1f0dafbd4f5,
+ 0xf1bccd8d7c31400,0xc3d700141b0fd8cc,0xf1bccd8d7c31400,0xc3d700141b0fd8cc,
+ 0xce0aca0ec004c400,0xe521e125eb2fef2b,0xce0aca0ec004c400,0xe521e125eb2fef2b,
+ 0xdd97f1bb662c4a00,0x96dcbaf02d67014b,0xdd97f1bb662c4a00,0x96dcbaf02d67014b,
+ 0x8756fd2cab7ad100,0xbda71a027f65d8c,0x8756fd2cab7ad100,0xbda71a027f65d8c,
+ 0x410b206a2b614a00,0xd69cb7fdbcf6dd97,0x410b206a2b614a00,0xd69cb7fdbcf6dd97,
+ 0x754acfff8ab5300,0x2f7c84d7d0837b28,0x754acfff8ab5300,0x2f7c84d7d0837b28,
+ 0xa9b4766bc2df1d00,0xeef3312c85985a47,0xa9b4766bc2df1d00,0xeef3312c85985a47,
+ 0x49820dc68f44cb00,0x8e45ca0148830cc7,0x49820dc68f44cb00,0x8e45ca0148830cc7,
+ 0xe97cc752bb2e9500,0x7ce952c72ebb0095,0xe97cc752bb2e9500,0x7ce952c72ebb0095,
+ 0x687d9c89e1f41500,0xd2c726335b4eafba,0x687d9c89e1f41500,0xd2c726335b4eafba,
+ 0x73eadc4536af9900,0x3da4920b78e1d74e,0x73eadc4536af9900,0x3da4920b78e1d74e,
+ 0xb8ad0a1fa7b21500,0x1005a2b70f1abda8,0xb8ad0a1fa7b21500,0x1005a2b70f1abda8,
+ 0x44f3fd4a0eb9b700,0xf4434dfabe0907b0,0x44f3fd4a0eb9b700,0xf4434dfabe0907b0,
+ 0x4e97f42d63bad900,0xa87112cb855c3fe6,0x4e97f42d63bad900,0xa87112cb855c3fe6,
+ 0x4d7e45763b083300,0x86b58ebdf0c3f8cb,0x4d7e45763b083300,0x86b58ebdf0c3f8cb,
+ 0x73b75f9be82cc400,0x71b55d99ea2ec602,0x73b75f9be82cc400,0x71b55d99ea2ec602,
+ 0x7b7ca3a4dfd80700,0x86815e592225fafd,0x7b7ca3a4dfd80700,0x86815e592225fafd,
+ 0x24ebe6290dc2cf00,0xae616ca38748458a,0x24ebe6290dc2cf00,0xae616ca38748458a,
+ 0x243cbba3879f1800,0xb3ab2c3410088f97,0x243cbba3879f1800,0xb3ab2c3410088f97,
+ 0xed17fd07ea10fa00,0x33c923d934ce24de,0xed17fd07ea10fa00,0x33c923d934ce24de,
+ 0x33b20f8ebd3c8100,0x9e1fa22310912cad,0x33b20f8ebd3c8100,0x9e1fa22310912cad,
+ 0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d,0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d,
+ 0x7768c0dfa8b71f00,0xe7f8504f38278f90,0x7768c0dfa8b71f00,0xe7f8504f38278f90,
+ 0x375bb2dee9856c00,0x2844adc1f69a731f,0x375bb2dee9856c00,0x2844adc1f69a731f,
+ 0xaf992f19b6803600,0x93a513258abc0a3c,0xaf992f19b6803600,0x93a513258abc0a3c,
+ 0x7a0f87f288fd7500,0xf1840c790376fe8b,0x7a0f87f288fd7500,0xf1840c790376fe8b,
+ 0x8015c752d2479500,0xcc598b1e9e0bd94c,0x8015c752d2479500,0xcc598b1e9e0bd94c,
+ 0x8023be1d9d3ea300,0x48eb76d555f66bc8,0x8023be1d9d3ea300,0x48eb76d555f66bc8,
+ 0x9c2f21920ebdb300,0x15a6a81b87343a89,0x9c2f21920ebdb300,0x15a6a81b87343a89,
+ 0x30d356b58566e300,0x8e6de80b3bd85dbe,0x30d356b58566e300,0x8e6de80b3bd85dbe,
+ 0xa9a6222d848b0f00,0xded1555af3fc7877,0xa9a6222d848b0f00,0xded1555af3fc7877,
+ 0xa7c9d9b7107e6e00,0x76180866c1afbfd1,0xa7c9d9b7107e6e00,0x76180866c1afbfd1,
+ 0x6c02f59bf7996e00,0x8ae4137d117f88e6,0x6c02f59bf7996e00,0x8ae4137d117f88e6,
+ 0xb31f2884379bac00,0xcc6057fb48e4d37f,0xb31f2884379bac00,0xcc6057fb48e4d37f,
+ 0x24dcd62e0af2f800,0x89717b83a75f55ad,0x24dcd62e0af2f800,0x89717b83a75f55ad,
+ 0xe29fdca1433e7d00,0xe79ad9a4463b7805,0xe29fdca1433e7d00,0xe79ad9a4463b7805,
+ 0x4f75caf0bf853a00,0xcdf748723d07b882,0x4f75caf0bf853a00,0xcdf748723d07b882,
+ 0x9ed3d69b05484d00,0x6924216cf2bfbaf7,0x9ed3d69b05484d00,0x6924216cf2bfbaf7,
+ 0x4bba837239c8f100,0x4bba837239c8f100,0x4bba837239c8f100,0x4bba837239c8f100,
+ 0xf0fe2a24d4da0e00,0x353befe1111fcbc5,0xf0fe2a24d4da0e00,0x353befe1111fcbc5,
+ 0xa1c3a5c766046200,0xb6d4b2d071137517,0xa1c3a5c766046200,0xb6d4b2d071137517,
+ 0x733a94ddaee74900,0xfeb71950236ac48d,0x733a94ddaee74900,0xfeb71950236ac48d,
+ 0x43b2906122d3f100,0x7081a35211e0c233,0x43b2906122d3f100,0x7081a35211e0c233,
+ 0x7281906311e2f300,0x9c6f7e8dff0c1dee,0x7281906311e2f300,0x9c6f7e8dff0c1dee,
+ 0x681709761e617f00,0x1a657b046c130d72,0x681709761e617f00,0x1a657b046c130d72,
+ 0xa7876040e7c7200,0xc7e7002087a7406,0xa7876040e7c7200,0xc7e7002087a7406,
+ 0xe747d2729535a000,0x379702a245e570d0,0xe747d2729535a000,0x379702a245e570d0,
+ 0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42,0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42,
+ 0xea8a4020caaa600,0x1bbdb11719bfb315,0xea8a4020caaa600,0x1bbdb11719bfb315,
+ 0xfd5343ed10beae00,0x832d3d936ec0d07e,0xfd5343ed10beae00,0x832d3d936ec0d07e,
+ 0xa5a5b3b316160000,0x71716767c2c2d4d4,0xa5a5b3b316160000,0x71716767c2c2d4d4,
+ 0x4ae8c262288aa00,0x2e84a60c08a2802a,0x4ae8c262288aa00,0x2e84a60c08a2802a,
+ 0xb5017ace7bcfb400,0xb4007bcf7aceb501,0xb5017ace7bcfb400,0xb4007bcf7aceb501,
+ 0xdddf42429f9d000,0xd2022bfbf6260fdf,0xdddf42429f9d000,0xd2022bfbf6260fdf,
+ 0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21,0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21,
+ 0x966f847deb12f900,0xf60fe41d8b729960,0x966f847deb12f900,0xf60fe41d8b729960,
+ 0xeca5ffb65a134900,0xe5acf6bf531a4009,0xeca5ffb65a134900,0xe5acf6bf531a4009,
+ 0xd286c49042165400,0x72266430e2b6f4a0,0xd286c49042165400,0x72266430e2b6f4a0,
+ 0xb02146d767f69100,0x62f39405b52443d2,0xb02146d767f69100,0x62f39405b52443d2,
+ 0xc563b214d177a600,0xe2449533f6508127,0xc563b214d177a600,0xe2449533f6508127,
+ 0x8d48ae6be623c500,0x509573b63bfe18dd,0x8d48ae6be623c500,0x509573b63bfe18dd,
+ 0xdc702d815df1ac00,0xf75b06aa76da872b,0xdc702d815df1ac00,0xf75b06aa76da872b,
+ 0x7452b395e1c72600,0x90b657710523c2e4,0x7452b395e1c72600,0x90b657710523c2e4,
+ 0xb8480cfc44b4f000,0x50a0e414ac5c18e8,0xb8480cfc44b4f000,0x50a0e414ac5c18e8,
+ 0xc11072a362b3d100,0xc61775a465b4d607,0xc11072a362b3d100,0xc61775a465b4d607,
+ 0x97bfa28a1d352800,0xc9e1fcd4436b765e,0x97bfa28a1d352800,0xc9e1fcd4436b765e,
+ 0xf62cd00afc26da00,0x429864be48926eb4,0xf62cd00afc26da00,0x429864be48926eb4,
+ 0x340cdee6d2ea3800,0x2b13c1f9cdf5271f,0x340cdee6d2ea3800,0x2b13c1f9cdf5271f,
+ 0x5fc8c156099e9700,0xd84f46d18e191087,0x5fc8c156099e9700,0xd84f46d18e191087,
+ 0x4cf36cd39f20bf00,0x11ae318ec27de25d,0x4cf36cd39f20bf00,0x11ae318ec27de25d,
+ 0xed2f2def02c0c200,0xaf6d6fad40828042,0xed2f2def02c0c200,0xaf6d6fad40828042,
+ 0x190da8bca5b11400,0xbfab0e1a0317b2a6,0x190da8bca5b11400,0xbfab0e1a0317b2a6,
+ 0x6d276e2449034a00,0x4309400a672d642e,0x6d276e2449034a00,0x4309400a672d642e,
+ 0xb3bda2ac1f110e00,0x323c232d9e908f81,0xb3bda2ac1f110e00,0x323c232d9e908f81,
+ 0x30e213c1f123d200,0x6cbe4f9dad7f8e5c,0x30e213c1f123d200,0x6cbe4f9dad7f8e5c,
+ 0x97ec790295ee7b00,0x4d36a3d84f34a1da,0x97ec790295ee7b00,0x4d36a3d84f34a1da,
+ 0x5cebbc0b57e0b700,0x6bdc8b3c60d78037,0x5cebbc0b57e0b700,0x6bdc8b3c60d78037,
+ 0x30380f07373f0800,0x60685f57676f5850,0x30380f07373f0800,0x60685f57676f5850,
+ 0xdc3dc121fd1ce00,0xe12f30fef33d22ec,0xdc3dc121fd1ce00,0xe12f30fef33d22ec,
+ 0xc7894a04c38d4e00,0x1d5390de195794da,0xc7894a04c38d4e00,0x1d5390de195794da,
+ 0xbb19ac0eb517a200,0x1bb90cae15b702a0,0xbb19ac0eb517a200,0x1bb90cae15b702a0,
+ 0x1e2c3d0f11233200,0xc3e2f1d03312012,0x1e2c3d0f11233200,0xc3e2f1d03312012,
+ 0x7af3e56c169f8900,0xd84921b61e8fe77,0x7af3e56c169f8900,0xd84921b61e8fe77,
+ 0xaa72409832ead800,0xfe2614cc66be8c54,0xaa72409832ead800,0xfe2614cc66be8c54,
+ 0xdcdd80815d5c0100,0xf2f3aeaf73722f2e,0xdcdd80815d5c0100,0xf2f3aeaf73722f2e,
+ 0xd8eae2d20a38300,0xbb38189b961535b6,0xd8eae2d20a38300,0xbb38189b961535b6,
+ 0x5add65e2b83f8700,0x68139bee463db5c,0x5add65e2b83f8700,0x68139bee463db5c,
+ 0x3b8450efd46bbf00,0xf946922d16a97dc2,0x3b8450efd46bbf00,0xf946922d16a97dc2,
+ 0x2d903885a815bd00,0x79c46cd1fc41e954,0x2d903885a815bd00,0x79c46cd1fc41e954,
+ 0xe3111def0cfef200,0xb3414dbf5caea250,0xe3111def0cfef200,0xb3414dbf5caea250,
+ 0xe19e2e51b0cf7f00,0x778c8b7562999e6,0xe19e2e51b0cf7f00,0x778c8b7562999e6,
+ 0x974cd803944fdb00,0x449f0bd0479c08d3,0x974cd803944fdb00,0x449f0bd0479c08d3,
+ 0xd92bf002db29f200,0x6f42fdd04f62ddf,0xd92bf002db29f200,0x6f42fdd04f62ddf,
+ 0xcb56a538f36e9d00,0x4996af73ca152cf,0xcb56a538f36e9d00,0x4996af73ca152cf,
+ 0x26238386a0a50500,0x838626230500a0a5,0x26238386a0a50500,0x838626230500a0a5,
+ 0xd6843c6eb8ea5200,0x7c2e96c41240f8aa,0xd6843c6eb8ea5200,0x7c2e96c41240f8aa,
+ 0x6f41e0cea18f2e00,0x755bfad4bb95341a,0x6f41e0cea18f2e00,0x755bfad4bb95341a,
+ 0x982e2e9800b6b600,0x67d1d167ff4949ff,0x982e2e9800b6b600,0x67d1d167ff4949ff,
+ 0xc2acd5bb79176e00,0xe688f19f5d334a24,0xc2acd5bb79176e00,0xe688f19f5d334a24,
+ 0x44aa14fabe50ee00,0x9876c826628c32dc,0x44aa14fabe50ee00,0x9876c826628c32dc,
+ 0x34a21482b6209600,0x63f543d5e177c157,0x34a21482b6209600,0x63f543d5e177c157,
+ 0x620cb8d6b4da6e00,0x46289cf290fe4a24,0x620cb8d6b4da6e00,0x46289cf290fe4a24,
+ 0xef7d0e9c73e19200,0x9f0d7eec0391e270,0xef7d0e9c73e19200,0x9f0d7eec0391e270,
+ 0x90f17d1c8ced6100,0xb0d15d3caccd4120,0x90f17d1c8ced6100,0xb0d15d3caccd4120,
+ 0xba7cd016ac6ac600,0xe4228e48f234985e,0xba7cd016ac6ac600,0xe4228e48f234985e,
+ 0xdb88ce9d46155300,0xa591f4c97c482d1,0xdb88ce9d46155300,0xa591f4c97c482d1,
+ 0xccf6734985bf3a00,0x7f45c0fa360c89b3,0xccf6734985bf3a00,0x7f45c0fa360c89b3,
+ 0xa6fee5bd1b435800,0xe4bca7ff59011a42,0xa6fee5bd1b435800,0xe4bca7ff59011a42,
+ 0x3ab029a399138a00,0x41cb52d8e268f17b,0x3ab029a399138a00,0x41cb52d8e268f17b,
+ 0x9b924d44dfd60900,0x343de2eb7079a6af,0x9b924d44dfd60900,0x343de2eb7079a6af,
+ 0x44ddc9591d84900,0x7039a8e1e5ac3d74,0x44ddc9591d84900,0x7039a8e1e5ac3d74,
+ 0xa1b1f8e849591000,0x617138288999d0c0,0xa1b1f8e849591000,0x617138288999d0c0,
+ 0xe26b4ac321a88900,0x1198b930d25b7af3,0xe26b4ac321a88900,0x1198b930d25b7af3,
+ 0x5940160f564f1900,0x372e78613821776e,0x5940160f564f1900,0x372e78613821776e,
+ 0xdbb2127ba0c96900,0x6a03a3ca1178d8b1,0xdbb2127ba0c96900,0x6a03a3ca1178d8b1,
+ 0x92639c6dff0ef100,0x72837c8d1fee11e0,0x92639c6dff0ef100,0x72837c8d1fee11e0,
+ 0xafa2bfb21d100d00,0x878a979a35382528,0xafa2bfb21d100d00,0x878a979a35382528,
+ 0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6,0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6,
+ 0xa9a28289202b0b00,0x4f44646fc6cdede6,0xa9a28289202b0b00,0x4f44646fc6cdede6,
+ 0xa4f592c367365100,0x6b3a5d0ca8f99ecf,0xa4f592c367365100,0x6b3a5d0ca8f99ecf,
+ 0xe3304c9f7cafd300,0xfd2e528162b1cd1e,0xe3304c9f7cafd300,0xfd2e528162b1cd1e,
+ 0xe6ca0529cfe32c00,0xdff33c10f6da1539,0xe6ca0529cfe32c00,0xdff33c10f6da1539,
+ 0xcd403cb17cf18d00,0xc74a36bb76fb870a,0xcd403cb17cf18d00,0xc74a36bb76fb870a,
+ 0xeda64f04e9a24b00,0x92d9307b96dd347f,0xeda64f04e9a24b00,0x92d9307b96dd347f,
+ 0x86be7941c7ff3800,0xf6ce0931b78f4870,0x86be7941c7ff3800,0xf6ce0931b78f4870,
+ 0x71a4a87d0cd9d500,0xcb1e12c7b6636fba,0x71a4a87d0cd9d500,0xcb1e12c7b6636fba,
+ 0x757d848cf9f10800,0x1911e8e0959d646c,0x757d848cf9f10800,0x1911e8e0959d646c,
+ 0xf0349e5aaa6ec400,0x9cd67a353973df9,0xf0349e5aaa6ec400,0x9cd67a353973df9,
+ 0x2d18d2e7caff3500,0x72478db895a06a5f,0x2d18d2e7caff3500,0x72478db895a06a5f,
+ 0x9e148a0a941e800,0x31d970989179d038,0x9e148a0a941e800,0x31d970989179d038,
+ 0xac55af56fa03f900,0x38c13bc26e976d94,0xac55af56fa03f900,0x38c13bc26e976d94,
+ 0x3c04a898a49c300,0xdc1f955655961cdf,0x3c04a898a49c300,0xdc1f955655961cdf,
+ 0x71cbc97302b8ba00,0x3b9bb0170cac872,0x71cbc97302b8ba00,0x3b9bb0170cac872,
+ 0xcecdf6f53b380300,0x7a7942418f8cb7b4,0xcecdf6f53b380300,0x7a7942418f8cb7b4,
+ 0x85d9f7ab2e725c00,0x48143a66e3bf91cd,0x85d9f7ab2e725c00,0x48143a66e3bf91cd,
+ 0x7275313644430700,0x90e4a4d3f387c7b,0x7275313644430700,0x90e4a4d3f387c7b,
+ 0x8e1fef7ef0619100,0x3aab5bca44d525b4,0x8e1fef7ef0619100,0x3aab5bca44d525b4,
+ 0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc,0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc,
+ 0x933bcb63f058a800,0xd27a8a22b119e941,0x933bcb63f058a800,0xd27a8a22b119e941,
+ 0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc,0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc,
+ 0x469033e5a375d600,0xd701a27432e44791,0x469033e5a375d600,0xd701a27432e44791,
+ 0x5237fb9ecca96500,0x1f7ab6d381e4284d,0x5237fb9ecca96500,0x1f7ab6d381e4284d,
+ 0x7e7f3c3d43420100,0x8180c3c2bcbdfeff,0x7e7f3c3d43420100,0x8180c3c2bcbdfeff,
+ 0x68688f8fe7e70000,0xe7e7000068688f8f,0x68688f8fe7e70000,0xe7e7000068688f8f,
+ 0x2211d8ebc9fa3300,0xddee27143605ccff,0x2211d8ebc9fa3300,0xddee27143605ccff,
+ 0x4e4e8484caca0000,0xf2f238387676bcbc,0x4e4e8484caca0000,0xf2f238387676bcbc,
+ 0x543dbad387ee6900,0xd3ba3d540069ee87,0x543dbad387ee6900,0xd3ba3d540069ee87,
+ 0xcccc1212dede0000,0x1b1bc5c50909d7d7,0xcccc1212dede0000,0x1b1bc5c50909d7d7,
+ 0xac45719834dde900,0x678eba53ff1622cb,0xac45719834dde900,0x678eba53ff1622cb,
+ 0x4b4b030348480000,0xfdfdb5b5fefeb6b6,0x4b4b030348480000,0xfdfdb5b5fefeb6b6,
+ 0x4e1d21723c6f5300,0x580b37642a794516,0x4e1d21723c6f5300,0x580b37642a794516,
+ 0x8a8a1e1e94940000,0xeaea7e7ef4f46060,0x8a8a1e1e94940000,0xeaea7e7ef4f46060,
+ 0xa1a8a5ac0d040900,0x8f868b82232a272e,0xa1a8a5ac0d040900,0x8f868b82232a272e,
+ 0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d,0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d,
+ 0xcbeecce922072500,0x8bae8ca962476540,0xcbeecce922072500,0x8bae8ca962476540,
+ 0xd5d53434e1e10000,0x606e7e73232d3d3,0xd5d53434e1e10000,0x606e7e73232d3d3,
+ 0x1897d8574fc08f00,0x36b9f67961eea12e,0x1897d8574fc08f00,0x36b9f67961eea12e,
+ 0x4949dede97970000,0xf8f86f6f2626b1b1,0x4949dede97970000,0xf8f86f6f2626b1b1,
+ 0x34e3f72014c3d700,0x35e2f62115c2d601,0x34e3f72014c3d700,0x35e2f62115c2d601,
+ 0x23f2e13112c3d00,0x576a7b4644796855,0x23f2e13112c3d00,0x576a7b4644796855,
+ 0x9a92424ad0d80800,0x6e66b6be242cfcf4,0x9a92424ad0d80800,0x6e66b6be242cfcf4,
+ 0x7874c9c5bdb10c00,0xe3ef525e262a979b,0x7874c9c5bdb10c00,0xe3ef525e262a979b,
+ 0x1083a93a2ab99300,0x891a30a3b3200a99,0x1083a93a2ab99300,0x891a30a3b3200a99,
+ 0xa4aa5d53f7f90e00,0x737d8a84202ed9d7,0xa4aa5d53f7f90e00,0x737d8a84202ed9d7,
+ 0x8cd5540d81d85900,0x851d089055cdd84,0x8cd5540d81d85900,0x851d089055cdd84,
+ 0x4047060141460700,0x4542030444430205,0x4047060141460700,0x4542030444430205,
+ 0x4fa4be551af1eb00,0x2ac1db307f948e65,0x4fa4be551af1eb00,0x2ac1db307f948e65,
+ 0xdded3303deee3000,0xdded3303deee3000,0xdded3303deee3000,0xdded3303deee3000,
+ 0x90a85868f8c0300,0x2122adaea7a42b28,0x90a85868f8c0300,0x2122adaea7a42b28,
+ 0x901f3ab525aa8f00,0xa827028d1d92b738,0x901f3ab525aa8f00,0xa827028d1d92b738,
+ 0x4c12b4eaa6f85e00,0x5709aff1bde3451b,0x4c12b4eaa6f85e00,0x5709aff1bde3451b,
+ 0x7025e1b4c4915500,0x90c501542471b5e0,0x7025e1b4c4915500,0x90c501542471b5e0,
+ 0xc1b45227e6937500,0x4336d0a56411f782,0xc1b45227e6937500,0x4336d0a56411f782,
+ 0xfe1011ff01efee00,0x28c6c729d73938d6,0xfe1011ff01efee00,0x28c6c729d73938d6,
+ 0x8228ba109238aa00,0x7ad3f9517bd2f85,0x8228ba109238aa00,0x7ad3f9517bd2f85,
+ 0xb79b200cbb972c00,0x19358ea2153982ae,0xb79b200cbb972c00,0x19358ea2153982ae,
+ 0x6fa25b96f934cd00,0x458871bcd31ee72a,0x6fa25b96f934cd00,0x458871bcd31ee72a,
+ 0x21e2c40726e5c300,0xf13214d7f63513d0,0x21e2c40726e5c300,0xf13214d7f63513d0,
+ 0x8c8aded854520600,0xdbdd898f03055157,0x8c8aded854520600,0xdbdd898f03055157,
+ 0x6e190d7a14637700,0x92e5f186e89f8bfc,0x6e190d7a14637700,0x92e5f186e89f8bfc,
+ 0x4fdd099bd4469200,0x168450c28d1fcb59,0x4fdd099bd4469200,0x168450c28d1fcb59,
+ 0xec7e92927eec00,0x5db123cfcf23b15d,0xec7e92927eec00,0x5db123cfcf23b15d,
+ 0x7e10177907696e00,0xe08e89e799f7f09e,0x7e10177907696e00,0xe08e89e799f7f09e,
+ 0xbb5dd2348f69e600,0xcb2da244ff199670,0xbb5dd2348f69e600,0xcb2da244ff199670,
+ 0x87f62151d6a7700,0x88ffe2959deaf780,0x87f62151d6a7700,0x88ffe2959deaf780,
+ 0x791cb9dca5c06500,0x5e3b9efb82e74227,0x791cb9dca5c06500,0x5e3b9efb82e74227,
+ 0x87b3a39710243400,0xa49080b433071723,0x87b3a39710243400,0xa49080b433071723,
+ 0xde2ec737e919f000,0x6f9f768658a841b1,0xde2ec737e919f000,0x6f9f768658a841b1,
+ 0x5ab74dadf71ae00,0x228c53fdf8568927,0x5ab74dadf71ae00,0x228c53fdf8568927,
+ 0xbb832018a39b3800,0x84bc1f279ca4073f,0xbb832018a39b3800,0x84bc1f279ca4073f,
+ 0xb0f8b2fa4a024800,0x84cc86ce7e367c34,0xb0f8b2fa4a024800,0x84cc86ce7e367c34,
+ 0x6f1e42335c2d7100,0xc0b1ed9cf382deaf,0x6f1e42335c2d7100,0xc0b1ed9cf382deaf,
+ 0x7a8ea0542edaf400,0xcd3917e3996d43b7,0x7a8ea0542edaf400,0xcd3917e3996d43b7,
+ 0x7f33175b24684c00,0x3d715519662a0e42,0x7f33175b24684c00,0x3d715519662a0e42,
+ 0xf7c41221d6e53300,0x8dbe685bac9f497a,0xf7c41221d6e53300,0x8dbe685bac9f497a,
+ 0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff,0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff,
+ 0x8405f170f4758100,0xd455a120a425d150,0x8405f170f4758100,0xd455a120a425d150,
+ 0xb240a85ae81af200,0x699b738133c129db,0xb240a85ae81af200,0x699b738133c129db,
+ 0xdead5724fa897300,0x592ad0a37d0ef487,0xdead5724fa897300,0x592ad0a37d0ef487,
+ 0x68201c543c744800,0x723a064e266e521a,0x68201c543c744800,0x723a064e266e521a,
+ 0x219acb7051eabb00,0x9b2071caeb5001ba,0x219acb7051eabb00,0x9b2071caeb5001ba,
+ 0x80b75562e2d53700,0x536486b13106e4d3,0x80b75562e2d53700,0x536486b13106e4d3,
+ 0x6d91f9056894fc00,0x6995fd016c90f804,0x6d91f9056894fc00,0x6995fd016c90f804,
+ 0x5cb17895c924ed00,0x668b42aff31ed73a,0x5cb17895c924ed00,0x668b42aff31ed73a,
+ 0x5a4f55451f0a100,0x1abbea4b4eefbe1f,0x5a4f55451f0a100,0x1abbea4b4eefbe1f,
+ 0x32bcaa2416988e00,0x73fdeb6557d9cf41,0x32bcaa2416988e00,0x73fdeb6557d9cf41,
+ 0xda3d44a3799ee700,0x43a4dd3ae0077e99,0xda3d44a3799ee700,0x43a4dd3ae0077e99,
+ 0xf9d25b7089a22b00,0x6e45cce71e35bc97,0xf9d25b7089a22b00,0x6e45cce71e35bc97,
+ 0x67c341e58226a400,0xe94dcf6b0ca82a8e,0x67c341e58226a400,0xe94dcf6b0ca82a8e,
+ 0xdbae7b0ed5a07500,0x205580f52e5b8efb,0xdbae7b0ed5a07500,0x205580f52e5b8efb,
+ 0x5d8528f8a57dd00,0x24f973aeab76fc21,0x5d8528f8a57dd00,0x24f973aeab76fc21,
+ 0xac027cd27ed0ae00,0xea0de70dc720ca2,0xac027cd27ed0ae00,0xea0de70dc720ca2,
+ 0x1c90da564ac68c00,0x911d57dbc74b018d,0x1c90da564ac68c00,0x911d57dbc74b018d,
+ 0xc04c5ad6169a8c00,0x1a96800ccc4056da,0xc04c5ad6169a8c00,0x1a96800ccc4056da,
+ 0xfadf2c09f3d62500,0x3411e2c73d18ebce,0xfadf2c09f3d62500,0x3411e2c73d18ebce,
+ 0xcf77e35b942cb800,0xb901952de25ace76,0xcf77e35b942cb800,0xb901952de25ace76,
+ 0xf46a9806f26c9e00,0x31af5dc337a95bc5,0xf46a9806f26c9e00,0x31af5dc337a95bc5,
+ 0xf0fee9e717190e00,0xb4baada3535d4a44,0xf0fee9e717190e00,0xb4baada3535d4a44,
+ 0x845b06d95d82df00,0xf12e73ac28f7aa75,0x845b06d95d82df00,0xf12e73ac28f7aa75,
+ 0x2b745b042f705f00,0xda85aaf5de81aef1,0x2b745b042f705f00,0xda85aaf5de81aef1,
+ 0x2f65561c33794a00,0x713b08426d27145e,0x2f65561c33794a00,0x713b08426d27145e,
+ 0x21f25586a774d300,0x33e04794b566c112,0x21f25586a774d300,0x33e04794b566c112,
+ 0xb3d27d1cafce6100,0xe0812e4ffc9d3253,0xb3d27d1cafce6100,0xe0812e4ffc9d3253,
+ 0x11fc34d9c825ed00,0xa74a826f7e935bb6,0x11fc34d9c825ed00,0xa74a826f7e935bb6,
+ 0x596d77431a2e3400,0x3f0b11257c485266,0x596d77431a2e3400,0x3f0b11257c485266,
+ 0x5c7f684b17342300,0x1c3f280b57746340,0x5c7f684b17342300,0x1c3f280b57746340,
+ 0xfee4b5af514b1a00,0x554f1e04fae0b1ab,0xfee4b5af514b1a00,0x554f1e04fae0b1ab,
+ 0x573c7a11462d6b00,0x5932741f4823650e,0x573c7a11462d6b00,0x5932741f4823650e,
+ 0x624e476b09252c00,0xe222b076549406c,0x624e476b09252c00,0xe222b076549406c,
+ 0xf58f6e14e19b7a00,0x2258b9c3364cadd7,0xf58f6e14e19b7a00,0x2258b9c3364cadd7,
+ 0x24e65a98bc7ec200,0x75b70bc9ed2f9351,0x24e65a98bc7ec200,0x75b70bc9ed2f9351,
+ 0xafb4445ff0eb1b00,0x8c97677cd3c83823,0xafb4445ff0eb1b00,0x8c97677cd3c83823,
+ 0xd2277f8a58adf500,0xe81d45b06297cf3a,0xd2277f8a58adf500,0xe81d45b06297cf3a,
+ 0xdef1b39c426d2f00,0x113e7c538da2e0cf,0xdef1b39c426d2f00,0x113e7c538da2e0cf,
+ 0x99667d821be4ff00,0xce312ad54cb3a857,0x99667d821be4ff00,0xce312ad54cb3a857,
+ 0xc62dfe15d338eb00,0x5eb5668d4ba07398,0xc62dfe15d338eb00,0x5eb5668d4ba07398,
+ 0xfbe60d1de6fb100,0x3e8f51e0ef5e8031,0xfbe60d1de6fb100,0x3e8f51e0ef5e8031,
+ 0x63d544f29127b600,0x3b52492f147d660,0x63d544f29127b600,0x3b52492f147d660,
+ 0x2ce728e3cf04cb00,0xaf64ab604c874883,0x2ce728e3cf04cb00,0xaf64ab604c874883,
+ 0xefda7a4fa0953500,0x8bbe1e2bc4f15164,0xefda7a4fa0953500,0x8bbe1e2bc4f15164,
+ 0x160f435a4c551900,0x3128647d6b723e27,0x160f435a4c551900,0x3128647d6b723e27,
+ 0x6ef775ec821b9900,0xcf56d44d23ba38a1,0x6ef775ec821b9900,0xcf56d44d23ba38a1,
+ 0xde0f11c11fced00,0xa74a5bb6bb5647aa,0xde0f11c11fced00,0xa74a5bb6bb5647aa,
+ 0xdb953f71aae44e00,0x82cc6628f3bd1759,0xdb953f71aae44e00,0x82cc6628f3bd1759,
+ 0xf42b37e81cc3df00,0xd30c10cf3be4f827,0xf42b37e81cc3df00,0xd30c10cf3be4f827,
+ 0x7c51c6eb97ba2d00,0x406dfad7ab86113c,0x7c51c6eb97ba2d00,0x406dfad7ab86113c,
+ 0x1c39ffdac6e32500,0x604583a6ba9f597c,0x1c39ffdac6e32500,0x604583a6ba9f597c,
+ 0x8ef7126be59c7900,0xfb82671e90e90c75,0x8ef7126be59c7900,0xfb82671e90e90c75,
+ 0xffafaafa05555000,0xfcaca9f906565303,0xffafaafa05555000,0xfcaca9f906565303,
+ 0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc,0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc,
+ 0x9f4aa277e83dd500,0x1fca22f768bd5580,0x9f4aa277e83dd500,0x1fca22f768bd5580,
+ 0x6b01b6dcb7dd6a00,0x244ef993f892254f,0x6b01b6dcb7dd6a00,0x244ef993f892254f,
+ 0x76f9da5523ac8f00,0xaa250689ff7053dc,0x76f9da5523ac8f00,0xaa250689ff7053dc,
+ 0x166bf78a9ce17d00,0x7d009ce1f78a166b,0x166bf78a9ce17d00,0x7d009ce1f78a166b,
+ 0x30e6e33505d3d600,0x78aeab7d4d9b9e48,0x30e6e33505d3d600,0x78aeab7d4d9b9e48,
+ 0x20b2a03212809200,0xa93b29bb9b091b89,0x20b2a03212809200,0xa93b29bb9b091b89,
+ 0xf3aff6aa59055c00,0x570b520efda1f8a4,0xf3aff6aa59055c00,0x570b520efda1f8a4,
+ 0xfba60c51aaf75d00,0xb5e8421fe4b9134e,0xfba60c51aaf75d00,0xb5e8421fe4b9134e,
+ 0xa3628849ea2bc100,0xa0618b4ae928c203,0xa3628849ea2bc100,0xa0618b4ae928c203,
+ 0xd1fc2d00d1fc2d00,0xcee3321fcee3321f,0xd1fc2d00d1fc2d00,0xcee3321fcee3321f,
+ 0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46,0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46,
+ 0x8647dc1d9b5ac100,0xa465fe3fb978e322,0x8647dc1d9b5ac100,0xa465fe3fb978e322,
+ 0xb9bd84843d39000,0x2dbdfe6e65f5b626,0xb9bd84843d39000,0x2dbdfe6e65f5b626,
+ 0x82ab577efcd52900,0x5a738fa6240df1d8,0x82ab577efcd52900,0x5a738fa6240df1d8,
+ 0xb1f9246cdd954800,0x18508dc5743ce1a9,0xb1f9246cdd954800,0x18508dc5743ce1a9,
+ 0x5697814117d6c00,0xed8190fcf99584e8,0x5697814117d6c00,0xed8190fcf99584e8,
+ 0x2249e78caec56b00,0x660da3c8ea812f44,0x2249e78caec56b00,0x660da3c8ea812f44,
+ 0x93f0610291f26300,0xe6851477e4871675,0x93f0610291f26300,0xe6851477e4871675,
+ 0x4a84c8064c82ce00,0x65abe72963ade12f,0x4a84c8064c82ce00,0x65abe72963ade12f,
+ 0x8670ce38be48f600,0x7f8937c147b10ff9,0x8670ce38be48f600,0x7f8937c147b10ff9,
+ 0xbfd2cea31c716d00,0x6e031f72cda0bcd1,0xbfd2cea31c716d00,0x6e031f72cda0bcd1,
+ 0x89167be46df29f00,0xd74825ba33acc15e,0x89167be46df29f00,0xd74825ba33acc15e,
+ 0x6b3d2472194f5600,0xe7b1a8fe95c3da8c,0x6b3d2472194f5600,0xe7b1a8fe95c3da8c,
+ 0x80ce80ce4e004e00,0x501e501e9ed09ed0,0x80ce80ce4e004e00,0x501e501e9ed09ed0,
+ 0x5ac31089d34a9900,0x77ee3da4fe67b42d,0x5ac31089d34a9900,0x77ee3da4fe67b42d,
+ 0x775398bccbef2400,0x2b0fc4e097b3785c,0x775398bccbef2400,0x2b0fc4e097b3785c,
+ 0xa7f21742e5b05500,0x5104e1b41346a3f6,0xa7f21742e5b05500,0x5104e1b41346a3f6,
+ 0xceb2fc8c423e700,0x29ce0aede106c225,0xceb2fc8c423e700,0x29ce0aede106c225,
+ 0x67ffe57d1a829800,0x56ced44c2bb3a931,0x67ffe57d1a829800,0x56ced44c2bb3a931,
+ 0xb42767f440d39300,0x59ca8a19ad3e7eed,0xb42767f440d39300,0x59ca8a19ad3e7eed,
+ 0x4f612d034c622e00,0xd3fdb19fd0feb29c,0x4f612d034c622e00,0xd3fdb19fd0feb29c,
+ 0x9750c90e995ec700,0xf433aa6dfa3da463,0x9750c90e995ec700,0xf433aa6dfa3da463,
+ 0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4,0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4,
+ 0x931b951d8e068800,0xd850b831098169e,0x931b951d8e068800,0xd850b831098169e,
+ 0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c,0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c,
+ 0xa3548671d225f700,0x2cdb09fe5daa788f,0xa3548671d225f700,0x2cdb09fe5daa788f,
+ 0x1d41184459055c00,0xc29ec79b86da83df,0x1d41184459055c00,0xc29ec79b86da83df,
+ 0x7ace1ca8d266b400,0xa511c3770db96bdf,0x7ace1ca8d266b400,0xa511c3770db96bdf,
+ 0x392d697d44501400,0x8c98dcc8f1e5a1b5,0x392d697d44501400,0x8c98dcc8f1e5a1b5,
+ 0x6b74554a213e1f00,0x9a85a4bbd0cfeef1,0x6b74554a213e1f00,0x9a85a4bbd0cfeef1,
+ 0xd0eb073cecd73b00,0xbd866a5181ba566d,0xd0eb073cecd73b00,0xbd866a5181ba566d,
+ 0xb44c25dd6991f800,0x1ee68f77c33b52aa,0xb44c25dd6991f800,0x1ee68f77c33b52aa,
+ 0xe65a338f69d5bc00,0x942841fd1ba7ce72,0xe65a338f69d5bc00,0x942841fd1ba7ce72,
+ 0xe32c8f40a36ccf00,0xa966c50ae926854a,0xe32c8f40a36ccf00,0xa966c50ae926854a,
+ 0x1fa2813c239ebd00,0x84391aa7b805269b,0x1fa2813c239ebd00,0x84391aa7b805269b,
+ 0x83ddfca2217f5e00,0xffa180de5d03227c,0x83ddfca2217f5e00,0xffa180de5d03227c,
+ 0x486c0521694d2400,0x76523b1f57731a3e,0x486c0521694d2400,0x76523b1f57731a3e,
+ 0xb37b3af24189c800,0xc20a4b8330f8b971,0xb37b3af24189c800,0xc20a4b8330f8b971,
+ 0xd5a0205580f57500,0x2055d5a0750080f5,0xd5a0205580f57500,0x2055d5a0750080f5,
+ 0xebef84806b6f0400,0xeeea81856e6a0105,0xebef84806b6f0400,0xeeea81856e6a0105,
+ 0xef2033fc13dccf00,0xcf0013dc33fcef20,0xef2033fc13dccf00,0xcf0013dc33fcef20,
+ 0x3f983493ac0ba700,0xac0ba7003f983493,0x3f983493ac0ba700,0xac0ba7003f983493,
+ 0x29483c5d74156100,0xd0b1c5a48dec98f9,0x29483c5d74156100,0xd0b1c5a48dec98f9,
+ 0xfbc34b7388b03800,0xf8c048708bb33b03,0xfbc34b7388b03800,0xf8c048708bb33b03,
+ 0x86d8b6e86e305e00,0x732d431d9bc5abf5,0x86d8b6e86e305e00,0x732d431d9bc5abf5,
+ 0x6626014127674000,0xc484a3e385c5e2a2,0x6626014127674000,0xc484a3e385c5e2a2,
+ 0x37cea0596e97f900,0x6b92fc0532cba55c,0x37cea0596e97f900,0x6b92fc0532cba55c,
+ 0x1bbc73d4cf68a700,0xff5897302b8c43e4,0x1bbc73d4cf68a700,0xff5897302b8c43e4,
+ 0x3ca6e27844de9a00,0xf95d14b77eda933,0x3ca6e27844de9a00,0xf95d14b77eda933,
+ 0x1da2e25d40ffbf00,0xdc63239c813e7ec1,0x1da2e25d40ffbf00,0xdc63239c813e7ec1,
+ 0x3ebcde5c62e08200,0x47c5a7251b99fb79,0x3ebcde5c62e08200,0x47c5a7251b99fb79,
+ 0x6110cbbadbaa7100,0xbbca11600170abda,0x6110cbbadbaa7100,0xbbca11600170abda,
+ 0x53fead0d5ef3a00,0xbe84516b6e5481bb,0x53fead0d5ef3a00,0xbe84516b6e5481bb,
+ 0x5ac17fe4be259b00,0x33a8168dd74cf269,0x5ac17fe4be259b00,0x33a8168dd74cf269,
+ 0x873ec47dfa43b900,0x62db21981fa65ce5,0x873ec47dfa43b900,0x62db21981fa65ce5,
+ 0xad2b4fc964e28600,0xc14723a5088eea6c,0xad2b4fc964e28600,0xc14723a5088eea6c,
+ 0xdda5ceb66b137800,0x463e552df088e39b,0xdda5ceb66b137800,0x463e552df088e39b,
+ 0x5c349ef6aac26800,0x1a72d8b0ec842e46,0x5c349ef6aac26800,0x1a72d8b0ec842e46,
+ 0xca96e3bf75295c00,0x4a16633ff5a9dc80,0xca96e3bf75295c00,0x4a16633ff5a9dc80,
+ 0xc26ecc6cae02a00,0x3319d3f9f5df153f,0xc26ecc6cae02a00,0x3319d3f9f5df153f,
+ 0xf9d55e728ba72c00,0xc5e9624eb79b103c,0xf9d55e728ba72c00,0xc5e9624eb79b103c,
+ 0x42bdd12e6c93ff00,0xe31c708fcd325ea1,0x42bdd12e6c93ff00,0xe31c708fcd325ea1,
+ 0xb594ba9b2e0f2100,0x31103e1faa8ba584,0xb594ba9b2e0f2100,0x31103e1faa8ba584,
+ 0xfd6b3bad50c69600,0xc9aca5ca13767f1,0xfd6b3bad50c69600,0xc9aca5ca13767f1,
+ 0xe3a77034d7934400,0xade93e7a99dd0a4e,0xe3a77034d7934400,0xade93e7a99dd0a4e,
+ 0x48763709417f3e00,0x3d03427c340a4b75,0x48763709417f3e00,0x3d03427c340a4b75,
+ 0x2228c8c2e0ea0a00,0x868c6c66444eaea4,0x2228c8c2e0ea0a00,0x868c6c66444eaea4,
+ 0x9cfff4970b686300,0x23404b28b4d7dcbf,0x9cfff4970b686300,0x23404b28b4d7dcbf,
+ 0xdc65ef568a33b900,0xe75ed46db108823b,0xdc65ef568a33b900,0xe75ed46db108823b,
+ 0x3867e7b880df5f00,0x732cacf3cb94144b,0x3867e7b880df5f00,0x732cacf3cb94144b,
+ 0x963f7fd640e9a900,0x359cdc75e34a0aa3,0x963f7fd640e9a900,0x359cdc75e34a0aa3,
+ 0x31b58f0b3abe8400,0xdf5b61e5d4506aee,0x31b58f0b3abe8400,0xdf5b61e5d4506aee,
+ 0xea316fb45e85db00,0xa8732df61cc79942,0xea316fb45e85db00,0xa8732df61cc79942,
+ 0xb5b54949fcfc0000,0x747488883d3dc1c1,0xb5b54949fcfc0000,0x747488883d3dc1c1,
+ 0x43d2910142d3900,0xedd4c0f9fdc4d0e9,0x43d2910142d3900,0xedd4c0f9fdc4d0e9,
+ 0xb31ea508bb16ad00,0x76db60cd7ed368c5,0xb31ea508bb16ad00,0x76db60cd7ed368c5,
+ 0xf6822e5aacd87400,0x1460ccb84e3a96e2,0xf6822e5aacd87400,0x1460ccb84e3a96e2,
+ 0xa78ae9c4634e2d00,0xe8c5a68b2c01624f,0xa78ae9c4634e2d00,0xe8c5a68b2c01624f,
+ 0x1dabcf7964d2b600,0xfd4b2f99843256e0,0x1dabcf7964d2b600,0xfd4b2f99843256e0,
+ 0xa315e452f147b600,0x259362d477c13086,0xa315e452f147b600,0x259362d477c13086,
+ 0x81d27320a1f25300,0x491abbe8693a9bc8,0x81d27320a1f25300,0x491abbe8693a9bc8,
+ 0xe7268b4aad6cc100,0x21e04d8c6baa07c6,0xe7268b4aad6cc100,0x21e04d8c6baa07c6,
+ 0x5a4e44540e1a100,0x2786c66762c38322,0x5a4e44540e1a100,0x2786c66762c38322,
+ 0x5d98b6732eebc500,0xe32608cd90557bbe,0x5d98b6732eebc500,0xe32608cd90557bbe,
+ 0x91943732a3a60500,0xc4c16267f6f35055,0x91943732a3a60500,0xc4c16267f6f35055,
+ 0x3e9008a69836ae00,0x5cf26ac4fa54cc62,0x3e9008a69836ae00,0x5cf26ac4fa54cc62,
+ 0x1f94d9524dc68b00,0xe9622fa4bb307df6,0x1f94d9524dc68b00,0xe9622fa4bb307df6,
+ 0xedbb1640adfb5600,0x194fe2b4590fa2f4,0xedbb1640adfb5600,0x194fe2b4590fa2f4,
+ 0x1836745a426c2e00,0xfed092bca48ac8e6,0x1836745a426c2e00,0xfed092bca48ac8e6,
+ 0xb7110dab1cbaa600,0x5ef8e442f5534fe9,0xb7110dab1cbaa600,0x5ef8e442f5534fe9,
+ 0x6347c2e685a12400,0xc8ec694d2e0a8fab,0x6347c2e685a12400,0xc8ec694d2e0a8fab,
+ 0xf3d59fb94a6c2600,0x89afe5c330165c7a,0xf3d59fb94a6c2600,0x89afe5c330165c7a,
+ 0xa5053c9c3999a000,0x4dedd474d17148e8,0xa5053c9c3999a000,0x4dedd474d17148e8,
+ 0xef21f43ad51bce00,0xc50bde10ff31e42a,0xef21f43ad51bce00,0xc50bde10ff31e42a,
+ 0x6263626301000100,0x585958593b3a3b3a,0x6263626301000100,0x585958593b3a3b3a,
+ 0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6,0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6,
+ 0xfe067f877981f800,0x1ae29b639d651ce4,0xfe067f877981f800,0x1ae29b639d651ce4,
+ 0xfb35e22cd719ce00,0xee20f739c20cdb15,0xfb35e22cd719ce00,0xee20f739c20cdb15,
+ 0xd262da6ab808b000,0x95259d2dff4ff747,0xd262da6ab808b000,0x95259d2dff4ff747,
+ 0x53c031a2f1629300,0xac3fce5d0e9d6cff,0x53c031a2f1629300,0xac3fce5d0e9d6cff,
+ 0x5b7bfede85a52000,0x86a623035878fddd,0x5b7bfede85a52000,0x86a623035878fddd,
+ 0xf9d43518e1cc2d00,0x8fa2436e97ba5b76,0xf9d43518e1cc2d00,0x8fa2436e97ba5b76,
+ 0x4edc63f1bf2d9200,0x68fa45d7990bb426,0x4edc63f1bf2d9200,0x68fa45d7990bb426,
+ 0xc964973af35ead00,0x45e81bb67fd2218c,0xc964973af35ead00,0x45e81bb67fd2218c,
+ 0x6f3d21731c4e5200,0x2f7d61335c0e1240,0x6f3d21731c4e5200,0x2f7d61335c0e1240,
+ 0x101df7faeae70d00,0x68658f82929f7578,0x101df7faeae70d00,0x68658f82929f7578,
+ 0x24aaa6280c828e00,0xa9272ba5810f038d,0x24aaa6280c828e00,0xa9272ba5810f038d,
+ 0xb34652a714e1f500,0x8d786c992adfcb3e,0xb34652a714e1f500,0x8d786c992adfcb3e,
+ 0x72bb8f4634fdc900,0x3af3c70e7cb58148,0x72bb8f4634fdc900,0x3af3c70e7cb58148,
+ 0xdff4361dc2e92b00,0xdbf03219c6ed2f04,0xdff4361dc2e92b00,0xdbf03219c6ed2f04,
+ 0x17e81ee1f609ff00,0x4db244bbac53a55a,0x17e81ee1f609ff00,0x4db244bbac53a55a,
+ 0xe3492e8467cdaa00,0xc66c0ba142e88f25,0xe3492e8467cdaa00,0xc66c0ba142e88f25,
+ 0xb062bd6fdf0dd200,0x13c11ecc7cae71a3,0xb062bd6fdf0dd200,0x13c11ecc7cae71a3,
+ 0xdbb1e68c573d6a00,0x6c06513be08addb7,0xdbb1e68c573d6a00,0x6c06513be08addb7,
+ 0x754797a5d0e23200,0x586aba88fdcf1f2d,0x754797a5d0e23200,0x586aba88fdcf1f2d,
+ 0xd5273cce1be9f200,0x83716a984dbfa456,0xd5273cce1be9f200,0x83716a984dbfa456,
+ 0xa522e767c245800,0x277f035b5109752d,0xa522e767c245800,0x277f035b5109752d,
+ 0xf302c938cb3af100,0xe415de2fdc2de617,0xf302c938cb3af100,0xe415de2fdc2de617,
+ 0x7a61d4cfb5ae1b00,0x869d28334952e7fc,0x7a61d4cfb5ae1b00,0x869d28334952e7fc,
+ 0x9b98797ae1e20300,0x5655b4b72c2fcecd,0x9b98797ae1e20300,0x5655b4b72c2fcecd,
+ 0x6601462147206700,0x6a0d4a2d4b2c6b0c,0x6601462147206700,0x6a0d4a2d4b2c6b0c,
+ 0x2e3668705e461800,0x140c524a647c223a,0x2e3668705e461800,0x140c524a647c223a,
+ 0x3223213002131100,0xeafbf9e8dacbc9d8,0x3223213002131100,0xeafbf9e8dacbc9d8,
+ 0x617a233859421b00,0x1c075e45243f667d,0x617a233859421b00,0x1c075e45243f667d,
+ 0x582df085dda87500,0xd1a4790c5421fc89,0x582df085dda87500,0xd1a4790c5421fc89,
+ 0xce8c3c7eb0f24200,0xf5b707458bc9793b,0xce8c3c7eb0f24200,0xf5b707458bc9793b,
+ 0x79743d3049440d00,0x808dc4c9b0bdf4f9,0x79743d3049440d00,0x808dc4c9b0bdf4f9,
+ 0x787edcdaa2a40600,0x5452f0f68e882a2c,0x787edcdaa2a40600,0x5452f0f68e882a2c,
+ 0xe427e427c300c300,0x93509350b477b477,0xe427e427c300c300,0x93509350b477b477,
+ 0xe1ab2d6786cc4a00,0xb9f3753fde941258,0xe1ab2d6786cc4a00,0xb9f3753fde941258,
+ 0x5b63d3ebb0883800,0xad95251d467ecef6,0x5b63d3ebb0883800,0xad95251d467ecef6,
+ 0xa6aebfb711190800,0x9b93828a2c24353d,0xa6aebfb711190800,0x9b93828a2c24353d,
+ 0xa84c28cc6480e400,0x42a6c2268e6a0eea,0xa84c28cc6480e400,0x42a6c2268e6a0eea,
+ 0xfd2827f20fdad500,0xa4717eab56838c59,0xfd2827f20fdad500,0xa4717eab56838c59,
+ 0xcb68f7549f3ca300,0x5dfe61c209aa3596,0xcb68f7549f3ca300,0x5dfe61c209aa3596,
+ 0x91fbb8d243296a00,0x9cf6b5df4e24670d,0x91fbb8d243296a00,0x9cf6b5df4e24670d,
+ 0x89da1546cf9c5300,0x7526e9ba3360affc,0x89da1546cf9c5300,0x7526e9ba3360affc,
+ 0xe6b22d799fcb5400,0xaafe6135d387184c,0xe6b22d799fcb5400,0xaafe6135d387184c,
+ 0xd5587dfd28a5800,0xf6ae7c242971a3fb,0xd5587dfd28a5800,0xf6ae7c242971a3fb,
+ };
+
+
+ alignas(32) const uint64_t i_beta_mul_64_bm4r_ext_8[2 * 128 * 4 * 2] = {
+ 0xb8b96a6bd3d20100,0x3e3feced55548786,0xb8b96a6bd3d20100,0x3e3feced55548786,
+ 0x80a06e4eceee2000,0x4d6da3830323edcd,0x80a06e4eceee2000,0x4d6da3830323edcd,
+ 0x8484a3a327270000,0xc1c1e6e662624545,0x8484a3a327270000,0xc1c1e6e662624545,
+ 0x34bf20ab9f148b00,0xf279e66d59d24dc6,0x34bf20ab9f148b00,0xf279e66d59d24dc6,
+ 0xe0e0cfcf2f2f0000,0x9595baba5a5a7575,0xe0e0cfcf2f2f0000,0x9595baba5a5a7575,
+ 0xbaf4420cb6f84e00,0x6f2197d9632d9bd5,0xbaf4420cb6f84e00,0x6f2197d9632d9bd5,
+ 0x9f9f5b5bc4c40000,0x606c2c25d5d9999,0x9f9f5b5bc4c40000,0x606c2c25d5d9999,
+ 0xc7a2e48146236500,0x82e7a1c403662045,0xc7a2e48146236500,0x82e7a1c403662045,
+ 0x606434345450000,0x2e2e6b6b6d6d2828,0x606434345450000,0x2e2e6b6b6d6d2828,
+ 0x5560182d784d3500,0xcbfe86b3e6d3ab9e,0x5560182d784d3500,0xcbfe86b3e6d3ab9e,
+ 0x48482e2e66660000,0x6767010149492f2f,0x48482e2e66660000,0x6767010149492f2f,
+ 0x286fd592bafd4700,0xbff842052d6ad097,0x286fd592bafd4700,0xbff842052d6ad097,
+ 0xc2c23434f6f60000,0x3d3dcbcb0909ffff,0xc2c23434f6f60000,0x3d3dcbcb0909ffff,
+ 0xc822d03af218ea00,0x4ca654be769c6e84,0xc822d03af218ea00,0x4ca654be769c6e84,
+ 0x3939d5d5ecec0000,0x66668a8ab3b35f5f,0x3939d5d5ecec0000,0x66668a8ab3b35f5f,
+ 0x1b858a140f919e00,0x6ff1fe607be5ea74,0x1b858a140f919e00,0x6ff1fe607be5ea74,
+ 0x7809f687ff8e7100,0xccbd42334b3ac5b4,0x7809f687ff8e7100,0xccbd42334b3ac5b4,
+ 0xa38f96ba19352c00,0x79554c60c3eff6da,0xa38f96ba19352c00,0x79554c60c3eff6da,
+ 0x434b2f27646c0800,0xcfc7a3abe8e0848c,0x434b2f27646c0800,0xcfc7a3abe8e0848c,
+ 0x5d0359075a045e00,0x1648124c114f154b,0x5d0359075a045e00,0x1648124c114f154b,
+ 0xd1df5e50818f0e00,0x4a44c5cb1a14959b,0xd1df5e50818f0e00,0x4a44c5cb1a14959b,
+ 0xacdfcab915667300,0x344752218dfeeb98,0xacdfcab915667300,0x344752218dfeeb98,
+ 0xaf3a15802fba9500,0x1a8fa0359a0f20b5,0xaf3a15802fba9500,0x1a8fa0359a0f20b5,
+ 0x9531d074e145a400,0x54f011b5208465c1,0x9531d074e145a400,0x54f011b5208465c1,
+ 0xbe1813b50bada600,0xa50308ae10b6bd1b,0xbe1813b50bada600,0xa50308ae10b6bd1b,
+ 0x5fd3d9550a868c00,0xbe3238b4eb676de1,0x5fd3d9550a868c00,0xbe3238b4eb676de1,
+ 0xacd1f58824597d00,0x304d6914b8c5e19c,0xacd1f58824597d00,0x304d6914b8c5e19c,
+ 0xfd6903976afe9400,0x72e68c18e5711b8f,0xfd6903976afe9400,0x72e68c18e5711b8f,
+ 0x8e6437dd53b9ea00,0xfe5b65cd2386b81,0x8e6437dd53b9ea00,0xfe5b65cd2386b81,
+ 0xe52cb970955cc900,0x1fd6438a6fa633fa,0xe52cb970955cc900,0x1fd6438a6fa633fa,
+ 0x17ad82382f95ba00,0x6cd6f94354eec17b,0x17ad82382f95ba00,0x6cd6f94354eec17b,
+ 0x30b3cb4878fb8300,0x3ebdc54676f58d0e,0x30b3cb4878fb8300,0x3ebdc54676f58d0e,
+ 0xc16d0fa362ceac00,0x16bad874b5197bd7,0xc16d0fa362ceac00,0x16bad874b5197bd7,
+ 0xbfab998d32261400,0xf1b293d8296a4b0,0xbfab998d32261400,0xf1b293d8296a4b0,
+ 0xc2f02113d1e33200,0xdbe9380ac8fa2b19,0xc2f02113d1e33200,0xdbe9380ac8fa2b19,
+ 0x5d04fba2ffa65900,0x154cb3eab7ee1148,0x5d04fba2ffa65900,0x154cb3eab7ee1148,
+ 0xdff8c5e23d1a2700,0x3c1b2601def9c4e3,0xdff8c5e23d1a2700,0x3c1b2601def9c4e3,
+ 0xbda7e2f8455f1a00,0x455f1a00bda7e2f8,0xbda7e2f8455f1a00,0x455f1a00bda7e2f8,
+ 0xe632ca1ef82cd400,0x29fd05d137e31bcf,0xe632ca1ef82cd400,0x29fd05d137e31bcf,
+ 0xe916b04fa659ff00,0x7c8325da33cc6a95,0xe916b04fa659ff00,0x7c8325da33cc6a95,
+ 0xf4a6ce9c683a5200,0x2270184abeec84d6,0xf4a6ce9c683a5200,0x2270184abeec84d6,
+ 0xc0b896ee2e567800,0x572f0179b9c1ef97,0xc0b896ee2e567800,0x572f0179b9c1ef97,
+ 0x2bb962f2d94b900,0x5ce5c87173cae75e,0x2bb962f2d94b900,0x5ce5c87173cae75e,
+ 0xee7055cb25bb9e00,0x5ec0e57b950b2eb0,0xee7055cb25bb9e00,0x5ec0e57b950b2eb0,
+ 0xee0a64846a8ee00,0x638dcb252bc5836d,0xee0a64846a8ee00,0x638dcb252bc5836d,
+ 0x2a483c5e74166200,0x593b4f2d07651173,0x2a483c5e74166200,0x593b4f2d07651173,
+ 0x49d02eb7fe679900,0x69f00e97de47b920,0x49d02eb7fe679900,0x69f00e97de47b920,
+ 0x9d978c861b110a00,0x8f859e9409031812,0x9d978c861b110a00,0x8f859e9409031812,
+ 0xe0d8073fdfe73800,0x6f5788b05068b78f,0xe0d8073fdfe73800,0x6f5788b05068b78f,
+ 0xe3219052b173c200,0xcd0fbe7c9f5dec2e,0xe3219052b173c200,0xcd0fbe7c9f5dec2e,
+ 0xf6b5c3837536400,0x593d0a6e61053256,0xf6b5c3837536400,0x593d0a6e61053256,
+ 0xd34abc25f66f9900,0x6bf2049d4ed721b8,0xd34abc25f66f9900,0x6bf2049d4ed721b8,
+ 0x8b55ad73f826de00,0x75ab538d06d820fe,0x8b55ad73f826de00,0x75ab538d06d820fe,
+ 0x4766d9f8bf9e2100,0xe9c8775611308fae,0x4766d9f8bf9e2100,0xe9c8775611308fae,
+ 0x3cfce2221edec000,0xa66678b884445a9a,0x3cfce2221edec000,0xa66678b884445a9a,
+ 0xfc51913cc06dad00,0x4de0208d71dc1cb1,0xfc51913cc06dad00,0x4de0208d71dc1cb1,
+ 0x876524c641a3e200,0xdf3d7c9e19fbba58,0x876524c641a3e200,0xdf3d7c9e19fbba58,
+ 0x4a8a985812d2c000,0x13d3c1014b8b9959,0x4a8a985812d2c000,0x13d3c1014b8b9959,
+ 0x5288449ecc16da00,0x23f935efbd67ab71,0x5288449ecc16da00,0x23f935efbd67ab71,
+ 0x4237126725507500,0x9eebcebbf98ca9dc,0x4237126725507500,0x9eebcebbf98ca9dc,
+ 0x3fe6954c73aad900,0x4f96e53c03daa970,0x3fe6954c73aad900,0x4f96e53c03daa970,
+ 0x47cfc64e09818800,0x24aca52d6ae2eb63,0x47cfc64e09818800,0x24aca52d6ae2eb63,
+ 0xb98b4476cffd3200,0xb587487ac3f13e0c,0xb98b4476cffd3200,0xb587487ac3f13e0c,
+ 0xe7b90e5eb9e7500,0xccb95227295cb7c2,0xe7b90e5eb9e7500,0xccb95227295cb7c2,
+ 0x3eff71b08e4fc100,0xe524aa6b55941adb,0x3eff71b08e4fc100,0xe524aa6b55941adb,
+ 0x476184a2e5c32600,0x99bf5a7c3b1df8de,0x476184a2e5c32600,0x99bf5a7c3b1df8de,
+ 0x63f89a0162f99b00,0x7ce7851e7de6841f,0x63f89a0162f99b00,0x7ce7851e7de6841f,
+ 0x4eba1de9a753f400,0x29dd7a8ec0349367,0x4eba1de9a753f400,0x29dd7a8ec0349367,
+ 0xe25fa914f64bbd00,0xec51a71af845b30e,0xe25fa914f64bbd00,0xec51a71af845b30e,
+ 0x52f72386d471a500,0x52f72386d471a500,0x52f72386d471a500,0x52f72386d471a500,
+ 0xf9c4023fc6fb3d00,0xa994526f96ab6d50,0xf9c4023fc6fb3d00,0xa994526f96ab6d50,
+ 0x925b25ec7eb7c900,0xea235d9406cfb178,0x925b25ec7eb7c900,0xea235d9406cfb178,
+ 0xbf963e17a8812900,0x755cf4dd624be3ca,0xbf963e17a8812900,0x755cf4dd624be3ca,
+ 0xe1b1baea0b5b5000,0x45151e4eaffff4a4,0xe1b1baea0b5b5000,0x45151e4eaffff4a4,
+ 0xaee791d8763f4900,0xa2eb9dd47a33450c,0xaee791d8763f4900,0xa2eb9dd47a33450c,
+ 0x17a511a3b406b200,0x17a511a3b406b200,0x17a511a3b406b200,0x17a511a3b406b200,
+ 0x2e6a9edaf4b04400,0xd59165210f4bbffb,0x2e6a9edaf4b04400,0xd59165210f4bbffb,
+ 0x87972e3eb9a91000,0x3a2a93830414adbd,0x87972e3eb9a91000,0x3a2a93830414adbd,
+ 0xe1bea0ff1e415f00,0xe4bba5fa1b445a05,0xe1bea0ff1e415f00,0xe4bba5fa1b445a05,
+ 0x689a7d8fe715f200,0x11e304f69e6c8b79,0x689a7d8fe715f200,0x11e304f69e6c8b79,
+ 0x4e20e48ac4aa6e00,0xc2ac68064826e28c,0x4e20e48ac4aa6e00,0xc2ac68064826e28c,
+ 0x91a40633a2973500,0xecd97b4edfea487d,0x91a40633a2973500,0xecd97b4edfea487d,
+ 0xe8e76b648c830f00,0xeee16d628a850906,0xe8e76b648c830f00,0xeee16d628a850906,
+ 0x462894fabcd26e00,0x8ce25e307618a4ca,0x462894fabcd26e00,0x8ce25e307618a4ca,
+ 0x5eddd0530d8e8300,0x82010c8fd1525fdc,0x5eddd0530d8e8300,0x82010c8fd1525fdc,
+ 0xbbba5e5fe4e50100,0xb0b15554efee0a0b,0xbbba5e5fe4e50100,0xb0b15554efee0a0b,
+ 0xff4363df209cbc00,0xbb7972bd46848f4,0xff4363df209cbc00,0xbb7972bd46848f4,
+ 0xe76235b057d28500,0x46c39411f67324a1,0xe76235b057d28500,0x46c39411f67324a1,
+ 0xfcd589a9557c200,0x589a0fcdc2009557,0xfcd589a9557c200,0x589a0fcdc2009557,
+ 0xda40cb518b119a00,0x4fd55ec41e840f95,0xda40cb518b119a00,0x4fd55ec41e840f95,
+ 0xeb7d17816afc9600,0xd84e24b259cfa533,0xeb7d17816afc9600,0xd84e24b259cfa533,
+ 0x86945e4ccad81200,0x1705cfdd5b498391,0x86945e4ccad81200,0x1705cfdd5b498391,
+ 0x496093baf3da2900,0x674ebd94ddf4072e,0x496093baf3da2900,0x674ebd94ddf4072e,
+ 0x43f8259edd66bb00,0x76cd10abe8538e35,0x43f8259edd66bb00,0x76cd10abe8538e35,
+ 0x82d6194dcf9b5400,0x5c08c79311458ade,0x82d6194dcf9b5400,0x5c08c79311458ade,
+ 0x2969195970304000,0xedaddd9db4f484c4,0x2969195970304000,0xedaddd9db4f484c4,
+ 0x886258b23ad0ea00,0x1ebd13bb3596389,0x886258b23ad0ea00,0x1ebd13bb3596389,
+ 0x2d15b888a59d300,0x13c04a999b48c211,0x2d15b888a59d300,0x13c04a999b48c211,
+ 0x28759fc2eab75d00,0xda876d301845aff2,0x28759fc2eab75d00,0xda876d301845aff2,
+ 0x88a8301098b82000,0x2c0c94b43c1c84a4,0x88a8301098b82000,0x2c0c94b43c1c84a4,
+ 0xa029008929a08900,0x73fad35afa735ad3,0xa029008929a08900,0x73fad35afa735ad3,
+ 0x6230ebb9db895200,0xa5f72c7e1c4e95c7,0x6230ebb9db895200,0xa5f72c7e1c4e95c7,
+ 0x4a76407c360a3c00,0xba86b08cc6faccf0,0x4a76407c360a3c00,0xba86b08cc6faccf0,
+ 0xf9d2ddf60f242b00,0xfad1def50c272803,0xf9d2ddf60f242b00,0xfad1def50c272803,
+ 0x4d4fd2d29f9d000,0xcdcf52521f1d808,0x4d4fd2d29f9d000,0xcdcf52521f1d808,
+ 0x82777c890bfef500,0x13e6ed189a6f6491,0x82777c890bfef500,0x13e6ed189a6f6491,
+ 0x135be8a0b3fb4800,0x99d1622a3971c28a,0x135be8a0b3fb4800,0x99d1622a3971c28a,
+ 0x35268a99acbf1300,0x5d4ee2f1c4d77b68,0x35268a99acbf1300,0x5d4ee2f1c4d77b68,
+ 0x881b74e76ffc9300,0x8f1c73e068fb9407,0x881b74e76ffc9300,0x8f1c73e068fb9407,
+ 0xb6acecf6405a1a00,0xf4eeaeb402185842,0xb6acecf6405a1a00,0xf4eeaeb402185842,
+ 0x1ad0559f854fca00,0x864cc90319d3569c,0x1ad0559f854fca00,0x864cc90319d3569c,
+ 0x632dc48ae9a74e00,0x9bd53c72115fb6f8,0x632dc48ae9a74e00,0x9bd53c72115fb6f8,
+ 0x6d0e4a2944276300,0x563571127f1c583b,0x6d0e4a2944276300,0x563571127f1c583b,
+ 0x5a2e24540e7a700,0x2b8ccc6b6ec9892e,0x5a2e24540e7a700,0x2b8ccc6b6ec9892e,
+ 0x9749fe2eb967d00,0x3e43a8d5dca14a37,0x9749fe2eb967d00,0x3e43a8d5dca14a37,
+ 0x42f53780c275b700,0x18af6dda982fed5a,0x42f53780c275b700,0x18af6dda982fed5a,
+ 0xef2dea28c705c200,0xa86aad6f80428547,0xef2dea28c705c200,0xa86aad6f80428547,
+ 0x884007cf478fc800,0x2ae2a56de52d6aa2,0x884007cf478fc800,0x2ae2a56de52d6aa2,
+ 0x959915198c800c00,0xbbb73b37a2ae222e,0x959915198c800c00,0xbbb73b37a2ae222e,
+ 0xf0209343b363d000,0xada69b949992afa,0xf0209343b363d000,0xada69b949992afa,
+ 0x5e9e90500ecec00,0xe90505e9ec0000ec,0x5e9e90500ecec00,0xe90505e9ec0000ec,
+ 0x9da5350d90a83800,0x774fdfe77a42d2ea,0x9da5350d90a83800,0x774fdfe77a42d2ea,
+ 0xf45f8328dc77ab00,0x2c875bf004af73d8,0xf45f8328dc77ab00,0x2c875bf004af73d8,
+ 0x40dd5ac7871a9d00,0x920f881555c84fd2,0x40dd5ac7871a9d00,0x920f881555c84fd2,
+ 0x35e7855762b0d200,0xcc1e7cae9b492bf9,0x35e7855762b0d200,0xcc1e7cae9b492bf9,
+ 0xd41beb24f03fcf00,0xae61915e8a45b57a,0xd41beb24f03fcf00,0xae61915e8a45b57a,
+ 0x424ce5eba9a70e00,0xb3bd141a5856fff1,0x424ce5eba9a70e00,0xb3bd141a5856fff1,
+ 0xa24630d47692e400,0xf612648022c6b054,0xa24630d47692e400,0xf612648022c6b054,
+ 0x24d033c7e317f400,0x20d437c3e713f004,0x24d033c7e317f400,0x20d437c3e713f004,
+ 0x39dad83b02e1e300,0x618280635ab9bb58,0x39dad83b02e1e300,0x618280635ab9bb58,
+ 0x79b4e12c5598cd00,0x74b9ec215895c00d,0x79b4e12c5598cd00,0x74b9ec215895c00d,
+ 0x35ddeb0336dee800,0xc62e18f0c52d1bf3,0x35ddeb0336dee800,0xc62e18f0c52d1bf3,
+ 0x6da45a93fe37c900,0x76bf4188e52cd21b,0x6da45a93fe37c900,0x76bf4188e52cd21b,
+ 0x7f0438433c477b00,0xa714d3649320e75,0x7f0438433c477b00,0xa714d3649320e75,
+ 0x6c85ee076b82e900,0x29c0ab422ec7ac45,0x6c85ee076b82e900,0x29c0ab422ec7ac45,
+ 0x977da74dda30ea00,0x3fd50fe5729842a8,0x977da74dda30ea00,0x3fd50fe5729842a8,
+ 0x7bcb08b8c373b000,0x6ddd1eaed565a616,0x7bcb08b8c373b000,0x6ddd1eaed565a616,
+ 0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440,0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440,
+ 0x3cea5a8cb066d600,0xe73181576bbd0ddb,0x3cea5a8cb066d600,0xe73181576bbd0ddb,
+ 0x23c5f61033d5e600,0xaf497a9cbf596a8c,0x23c5f61033d5e600,0xaf497a9cbf596a8c,
+ 0xd10ed40bda05df00,0xc21dc718c916cc13,0xd10ed40bda05df00,0xc21dc718c916cc13,
+ 0x3922cad1e8f31b00,0x2239d1caf3e8001b,0x3922cad1e8f31b00,0x2239d1caf3e8001b,
+ 0x71a2835322f1d00,0xa3be8c91968bb9a4,0x71a2835322f1d00,0xa3be8c91968bb9a4,
+ 0x7907403e47397e00,0xd0aee997ee90d7a9,0x7907403e47397e00,0xd0aee997ee90d7a9,
+ 0x6ba2ae670cc5c900,0x34fdf138539a965f,0x6ba2ae670cc5c900,0x34fdf138539a965f,
+ 0x34a18e1b2fba9500,0x42d7f86d59cce376,0x34a18e1b2fba9500,0x42d7f86d59cce376,
+ 0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171,0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171,
+ 0xa4d61b69cdbf7200,0x7d0fc2b01466abd9,0xa4d61b69cdbf7200,0x7d0fc2b01466abd9,
+ 0x83b92d1794ae3a00,0x9ea4300a89b3271d,0x83b92d1794ae3a00,0x9ea4300a89b3271d,
+ 0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc,0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc,
+ 0xf672fe7a8c088400,0x5ade52d620a428ac,0xf672fe7a8c088400,0x5ade52d620a428ac,
+ 0xc7785fe02798bf00,0x229dba05c27d5ae5,0xc7785fe02798bf00,0x229dba05c27d5ae5,
+ 0xbccbadda66117700,0x33442255e99ef88f,0xbccbadda66117700,0x33442255e99ef88f,
+ 0xec23d817fb34cf00,0xb9768d42ae619a55,0xec23d817fb34cf00,0xb9768d42ae619a55,
+ 0xf0095aa353aaf900,0x20d98a73837a29d0,0xf0095aa353aaf900,0x20d98a73837a29d0,
+ 0xb25329c87a9be100,0x7190ea0bb95822c3,0xb25329c87a9be100,0x7190ea0bb95822c3,
+ 0x5a963ff3a965cc00,0x7cb62aef438915d,0x5a963ff3a965cc00,0x7cb62aef438915d,
+ 0xe6d57d4ea89b3300,0x15268ebd5b68c0f3,0xe6d57d4ea89b3300,0x15268ebd5b68c0f3,
+ 0xe4c02404e0c4200,0x67256b2927652b69,0xe4c02404e0c4200,0x67256b2927652b69,
+ 0x9ef81177e98f6600,0xa2c42d4bd5b35a3c,0x9ef81177e98f6600,0xa2c42d4bd5b35a3c,
+ 0x21628fccedae4300,0x682bc685a4e70a49,0x21628fccedae4300,0x682bc685a4e70a49,
+ 0x97a399ad3a0e3400,0xdaeed4e07743794d,0x97a399ad3a0e3400,0xdaeed4e07743794d,
+ 0x3147f385b4c27600,0xd4a21660512793e5,0x3147f385b4c27600,0xd4a21660512793e5,
+ 0xf86d45d028bd9500,0x93062ebb43d6fe6b,0xf86d45d028bd9500,0x93062ebb43d6fe6b,
+ 0xa8f392c9613a5b00,0xb8e382d9712a4b10,0xa8f392c9613a5b00,0xb8e382d9712a4b10,
+ 0x7cf854d0ac288400,0xb135991d61e549cd,0x7cf854d0ac288400,0xb135991d61e549cd,
+ 0x95b8ad8015382d00,0xfed3c6eb7e53466b,0x95b8ad8015382d00,0xfed3c6eb7e53466b,
+ 0xac9f88bb17243300,0xbc8f98ab07342310,0xac9f88bb17243300,0xbc8f98ab07342310,
+ 0xe30920ca29c3ea00,0xec062fc526cce50f,0xe30920ca29c3ea00,0xec062fc526cce50f,
+ 0xf3d1f5d724062200,0x33113517e4c6e2c0,0xf3d1f5d724062200,0x33113517e4c6e2c0,
+ 0xc5ab523cf9976e00,0x9af40d63a6c8315f,0xc5ab523cf9976e00,0x9af40d63a6c8315f,
+ 0x3c5c84e4d8b86000,0x3e5e86e6daba6202,0x3c5c84e4d8b86000,0x3e5e86e6daba6202,
+ 0xe0207cbc5c9cc000,0xe92975b55595c909,0xe0207cbc5c9cc000,0xe92975b55595c909,
+ 0xc3a5355390f66600,0xf89e0e68abcd5d3b,0xc3a5355390f66600,0xf89e0e68abcd5d3b,
+ 0x92ab5168fac33900,0x3b02f8c1536a90a9,0x92ab5168fac33900,0x3b02f8c1536a90a9,
+ 0xb7014cfa4dfbb600,0x15a3ee58ef5914a2,0xb7014cfa4dfbb600,0x15a3ee58ef5914a2,
+ 0xf268ab31c3599a00,0xab31f2689a00c359,0xf268ab31c3599a00,0xab31f2689a00c359,
+ 0xe17f76e809979e00,0xb72920be5fc1c856,0xe17f76e809979e00,0xb72920be5fc1c856,
+ 0x3f76f9b08fc64900,0xfdb43b724d048bc2,0x3f76f9b08fc64900,0xfdb43b724d048bc2,
+ 0x31289c85b4ad1900,0xa8b1051c2d348099,0x31289c85b4ad1900,0xa8b1051c2d348099,
+ 0xa75e3bc2659cf900,0x6e97f20bac5530c9,0xa75e3bc2659cf900,0x6e97f20bac5530c9,
+ 0x222c414f6d630e00,0x6b650806242a4749,0x222c414f6d630e00,0x6b650806242a4749,
+ 0x52deb23e6ce08c00,0x800c60ecbe325ed2,0x52deb23e6ce08c00,0x800c60ecbe325ed2,
+ 0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab,0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab,
+ 0x8bb589b73c023e00,0x19271b25ae90ac92,0x8bb589b73c023e00,0x19271b25ae90ac92,
+ 0x764a9cacdae6300,0x566abc8cfac6102,0x764a9cacdae6300,0x566abc8cfac6102,
+ 0x81bdab97162a3c00,0x201c0a36b78b9da1,0x81bdab97162a3c00,0x201c0a36b78b9da1,
+ 0x8a3d992ea413b700,0x6add79ce44f357e0,0x8a3d992ea413b700,0x6add79ce44f357e0,
+ 0xbab43c3288860e00,0xfaf47c72c8c64e40,0xbab43c3288860e00,0xfaf47c72c8c64e40,
+ 0x33917edcef4da200,0x1ebc53f1c2608f2d,0x33917edcef4da200,0x1ebc53f1c2608f2d,
+ 0x29efdc1a33f5c600,0x4482b1775e98ab6d,0x29efdc1a33f5c600,0x4482b1775e98ab6d,
+ 0xe17e0e9170ef9f00,0x3da2d24dac3343dc,0xe17e0e9170ef9f00,0x3da2d24dac3343dc,
+ 0xa7bbffe344581c00,0xd2ce8a96312d6975,0xa7bbffe344581c00,0xd2ce8a96312d6975,
+ 0x1ca004b8a418bc00,0xbf03a71b07bb1fa3,0x1ca004b8a418bc00,0xbf03a71b07bb1fa3,
+ 0x7e66948cf2ea1800,0x948c7e661800f2ea,0x7e66948cf2ea1800,0x948c7e661800f2ea,
+ 0x224ca2ccee806e00,0x355bb5dbf9977917,0x224ca2ccee806e00,0x355bb5dbf9977917,
+ 0x4c52405e120c1e00,0xb1afbda3eff1e3fd,0x4c52405e120c1e00,0xb1afbda3eff1e3fd,
+ 0x80ec563abad66c00,0xb8d46e0282ee5438,0x80ec563abad66c00,0xb8d46e0282ee5438,
+ 0xeeb3d588663b5d00,0x64395f02ecb1d78a,0xeeb3d588663b5d00,0x64395f02ecb1d78a,
+ 0x53dfb73b68e48c00,0x64e8800c5fd3bb37,0x53dfb73b68e48c00,0x64e8800c5fd3bb37,
+ 0xfc5059f509a5ac00,0x3a969f33cf636ac6,0xfc5059f509a5ac00,0x3a969f33cf636ac6,
+ 0xcbd02932f9e21b00,0x51ee7fc372cd5ce,0xcbd02932f9e21b00,0x51ee7fc372cd5ce,
+ 0x5ba640bde61bfd00,0x9a67817c27da3cc1,0x5ba640bde61bfd00,0x9a67817c27da3cc1,
+ 0x565d8d86d0db0b00,0x565d8d86d0db0b00,0x565d8d86d0db0b00,0x565d8d86d0db0b00,
+ 0x8696afbf39291000,0x4f5f6676f0e0d9c9,0x8696afbf39291000,0x4f5f6676f0e0d9c9,
+ 0x916fc33dac52fe00,0xe51bb749d8268a74,0x916fc33dac52fe00,0xe51bb749d8268a74,
+ 0x92d47a3caee84600,0xda9c3274e6a00e48,0x92d47a3caee84600,0xda9c3274e6a00e48,
+ 0x26e9549bbd72cf00,0x1ed16ca3854af738,0x26e9549bbd72cf00,0x1ed16ca3854af738,
+ 0x32cb27deec15f900,0xaa53bf46748d6198,0x32cb27deec15f900,0xaa53bf46748d6198,
+ 0xcdb3e39d502e7e00,0xe896c6b8750b5b25,0xcdb3e39d502e7e00,0xe896c6b8750b5b25,
+ 0xc999bded24745000,0x21715505cc9cb8e8,0xc999bded24745000,0x21715505cc9cb8e8,
+ 0x280c6b4f67432400,0x795d3a1e36127551,0x280c6b4f67432400,0x795d3a1e36127551,
+ 0xd0ca859f4f551a00,0xf155a40908ac5df,0xd0ca859f4f551a00,0xf155a40908ac5df,
+ 0x5167d6e0b1873600,0x94a213257442f3c5,0x5167d6e0b1873600,0x94a213257442f3c5,
+ 0x43defd6d2eb3900,0xe0d90b32360fdde4,0x43defd6d2eb3900,0xe0d90b32360fdde4,
+ 0x417f98a6e7d93e00,0x13fd8e6a7997e40,0x417f98a6e7d93e00,0x13fd8e6a7997e40,
+ 0x34e96eb3875add00,0x20fd7aa7934ec914,0x34e96eb3875add00,0x20fd7aa7934ec914,
+ 0xaaa2464ee4ec0800,0x535bbfb71d15f1f9,0xaaa2464ee4ec0800,0x535bbfb71d15f1f9,
+ 0xf2a07725d7855200,0x7022f5a75507d082,0xf2a07725d7855200,0x7022f5a75507d082,
+ 0x89b34b71f8c23a00,0x7e44bc860f35cdf7,0x89b34b71f8c23a00,0x7e44bc860f35cdf7,
+ 0x47b6e11057a6f100,0xe71641b0f70651a0,0x47b6e11057a6f100,0xe71641b0f70651a0,
+ 0x1bc7fe2239e5dc00,0xb76b528e954970ac,0x1bc7fe2239e5dc00,0xb76b528e954970ac,
+ 0x5488db07538fdc00,0xe23e6db1e5396ab6,0x5488db07538fdc00,0xe23e6db1e5396ab6,
+ 0xf22c588674aade00,0xd80672ac5e80f42a,0xf22c588674aade00,0xd80672ac5e80f42a,
+ 0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2,0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2,
+ 0xde2ac430ee1af400,0x2f618ec32c628dc,0xde2ac430ee1af400,0x2f618ec32c628dc,
+ 0x3a0b8bba80b13100,0xf4c545744e7fffce,0x3a0b8bba80b13100,0xf4c545744e7fffce,
+ 0x2cdb1cebc730f700,0x9265a255798e49be,0x2cdb1cebc730f700,0x9265a255798e49be,
+ 0x56141d5f094b4200,0xf6b4bdffa9ebe2a0,0x56141d5f094b4200,0xf6b4bdffa9ebe2a0,
+ 0xb7ac455ee9f21b00,0xe7fc150eb9a24b50,0xb7ac455ee9f21b00,0xe7fc150eb9a24b50,
+ 0x968ad8c4524e1c00,0x21e4c50c6da8894,0x968ad8c4524e1c00,0x21e4c50c6da8894,
+ 0x1ddacc0b16d1c700,0x2cebfd3a27e0f631,0x1ddacc0b16d1c700,0x2cebfd3a27e0f631,
+ 0x28539be0c8b37b00,0x99e22a517902cab1,0x28539be0c8b37b00,0x99e22a517902cab1,
+ 0xc38281c003424100,0x91d0d39251101352,0xc38281c003424100,0x91d0d39251101352,
+ 0x8681beb93f380700,0xbeb9868107003f38,0x8681beb93f380700,0xbeb9868107003f38,
+ 0xefd77b43ac943800,0x122a86be5169c5fd,0xefd77b43ac943800,0x122a86be5169c5fd,
+ 0x9ec67e26b8e05800,0x366ed68e1048f0a8,0x9ec67e26b8e05800,0x366ed68e1048f0a8,
+ 0x875fed35b26ad800,0x71a91bc3449c2ef6,0x875fed35b26ad800,0x71a91bc3449c2ef6,
+ 0x2bc23ad3f811e900,0x78916980ab42ba53,0x2bc23ad3f811e900,0x78916980ab42ba53,
+ 0x2211417250633300,0xf0c393a082b1e1d2,0x2211417250633300,0xf0c393a082b1e1d2,
+ 0x6966303f56590f00,0xefe0b6b9d0df8986,0x6966303f56590f00,0xefe0b6b9d0df8986,
+ 0x1d93850b16988e00,0x38d9b150886901e,0x1d93850b16988e00,0x38d9b150886901e,
+ 0x6b48b497fcdf2300,0x81a25e7d1635c9ea,0x6b48b497fcdf2300,0x81a25e7d1635c9ea,
+ 0x40094a03430a4900,0xde97d49ddd94d79e,0x40094a03430a4900,0xde97d49ddd94d79e,
+ 0x74019aef9bee7500,0x4b3ea5d0a4d14a3f,0x74019aef9bee7500,0x4b3ea5d0a4d14a3f,
+ 0x36691c43752a5f00,0x2f70055a6c334619,0x36691c43752a5f00,0x2f70055a6c334619,
+ 0xbba91507bcae1200,0xcfdd6173c8da6674,0xbba91507bcae1200,0xcfdd6173c8da6674,
+ 0x2980993910b9a00,0xa90019b99039208,0x2980993910b9a00,0xa90019b99039208,
+ 0xfc3bb0778b4cc700,0xac6be027db1c9750,0xfc3bb0778b4cc700,0xac6be027db1c9750,
+ 0x70ed1f82f26f9d00,0x118c7ee3930efc61,0x70ed1f82f26f9d00,0x118c7ee3930efc61,
+ 0x8c5ac7119d4bd600,0xeb3da076fa2cb167,0x8c5ac7119d4bd600,0xeb3da076fa2cb167,
+ 0x8a18fe6ce6749200,0x9a08ee7cf6648210,0x8a18fe6ce6749200,0x9a08ee7cf6648210,
+ 0xfa5b48e913b2a100,0x75d4c7669c3d2e8f,0xfa5b48e913b2a100,0x75d4c7669c3d2e8f,
+ 0x6d660d066b600b00,0xd066d660b006b60,0x6d660d066b600b00,0xd066d660b006b60,
+ 0xc5c16763a6a20400,0xa8ac0a0ecbcf696d,0xc5c16763a6a20400,0xa8ac0a0ecbcf696d,
+ 0x1b48f2a1bae95300,0x4112a8fbe0b3095a,0x1b48f2a1bae95300,0x4112a8fbe0b3095a,
+ 0xcaca47478d8d0000,0x5c5cd1d11b1b9696,0xcaca47478d8d0000,0x5c5cd1d11b1b9696,
+ 0x56ac83792fd5fa00,0x976d42b8ee143bc1,0x56ac83792fd5fa00,0x976d42b8ee143bc1,
+ 0x9f9febeb74740000,0x13136767f8f88c8c,0x9f9febeb74740000,0x13136767f8f88c8c,
+ 0x13dbfd3526eec800,0x5098be7665ad8b43,0x13dbfd3526eec800,0x5098be7665ad8b43,
+ 0x65659f9ffafa0000,0x5252a8a8cdcd3737,0x65659f9ffafa0000,0x5252a8a8cdcd3737,
+ 0x96bf8da4321b2900,0x153c0e27b198aa83,0x96bf8da4321b2900,0x153c0e27b198aa83,
+ 0xf1f10909f8f80000,0x5656aeae5f5fa7a7,0xf1f10909f8f80000,0x5656aeae5f5fa7a7,
+ 0xf4d29bbd496f2600,0x2246d4bbf99d0f6,0xf4d29bbd496f2600,0x2246d4bbf99d0f6,
+ 0x3d3d0a0a37370000,0xe7e7d0d0ededdada,0x3d3d0a0a37370000,0xe7e7d0d0ededdada,
+ 0x1e4a8bdfc1955400,0xf4a061352b7fbeea,0x1e4a8bdfc1955400,0xf4a061352b7fbeea,
+ 0x1e1e565648480000,0x4c4c04041a1a5252,0x1e1e565648480000,0x4c4c04041a1a5252,
+ 0x5fbe36d78869e100,0xf5149c7d22c34baa,0x5fbe36d78869e100,0xf5149c7d22c34baa,
+ 0x7373efef9c9c0000,0x8f8f13136060fcfc,0x7373efef9c9c0000,0x8f8f13136060fcfc,
+ 0x1fe840b7a85ff700,0x4f35bacb344ec1b,0x1fe840b7a85ff700,0x4f35bacb344ec1b,
+ 0x6666ddddbbbb0000,0x6969d2d2b4b40f0f,0x6666ddddbbbb0000,0x6969d2d2b4b40f0f,
+ 0x423fa1dc9ee37d00,0x5e23bdc082ff611c,0x423fa1dc9ee37d00,0x5e23bdc082ff611c,
+ 0xca4b1b9a50d18100,0x1c9dcd4c860757d6,0xca4b1b9a50d18100,0x1c9dcd4c860757d6,
+ 0xba8993a3192a300,0xb81b2a89822110b3,0xba8993a3192a300,0xb81b2a89822110b3,
+ 0xa5ce99f2573c6b00,0xa8c394ff5a31660d,0xa5ce99f2573c6b00,0xa8c394ff5a31660d,
+ 0xab2831b2199a8300,0x5fdcc546ed6e77f4,0xab2831b2199a8300,0x5fdcc546ed6e77f4,
+ 0xf607a958ae5ff100,0xc83997669061cf3e,0xf607a958ae5ff100,0xc83997669061cf3e,
+ 0xa531fa6ecb5f9400,0x9b0fc450f561aa3e,0xa531fa6ecb5f9400,0x9b0fc450f561aa3e,
+ 0x7f39afe996d04600,0x9cda4c0a7533a5e3,0x7f39afe996d04600,0x9cda4c0a7533a5e3,
+ 0x7d1588e09df56800,0x86ee731b660e93fb,0x7d1588e09df56800,0x86ee731b660e93fb,
+ 0x52013f6c3e6d5300,0xaffcc291c390aefd,0x52013f6c3e6d5300,0xaffcc291c390aefd,
+ 0x488c79bdf531c400,0xdf1bee2a62a65397,0x488c79bdf531c400,0xdf1bee2a62a65397,
+ 0xd7a77303d4a47000,0xd2a27606d1a17505,0xd7a77303d4a47000,0xd2a27606d1a17505,
+ 0xb7ff7e3681c94800,0x145cdd95226aeba3,0xb7ff7e3681c94800,0x145cdd95226aeba3,
+ 0x6399c03a59a3fa00,0xd72d748eed174eb4,0x6399c03a59a3fa00,0xd72d748eed174eb4,
+ 0xd7ceb1a87f661900,0xf1e8978e59403f26,0xd7ceb1a87f661900,0xf1e8978e59403f26,
+ 0x5f3e98f9a6c76100,0x86e741207f1eb8d9,0x5f3e98f9a6c76100,0x86e741207f1eb8d9,
+ 0xcc31af529e63fd00,0x6c910ff23ec35da0,0xcc31af529e63fd00,0x6c910ff23ec35da0,
+ 0xe6a1b3f412554700,0xabecfeb95f180a4d,0xe6a1b3f412554700,0xabecfeb95f180a4d,
+ 0x37012f192e183600,0x6157794f784e6056,0x37012f192e183600,0x6157794f784e6056,
+ 0x286eca8ca4e24600,0x4600a4e2ca8c286e,0x286eca8ca4e24600,0x4600a4e2ca8c286e,
+ 0xca68f2509a38a200,0x8e2cb614de7ce644,0xca68f2509a38a200,0x8e2cb614de7ce644,
+ 0x5db2ee015cb3ef00,0xbc530fe0bd520ee1,0x5db2ee015cb3ef00,0xbc530fe0bd520ee1,
+ 0xf92f00d62ff9d600,0x15c3ec3ac3153aec,0xf92f00d62ff9d600,0x15c3ec3ac3153aec,
+ 0xb25147a416f5e300,0xf41701e250b3a546,0xb25147a416f5e300,0xf41701e250b3a546,
+ 0x9dbd22029fbf2000,0xad8d1232af8f1030,0x9dbd22029fbf2000,0xad8d1232af8f1030,
+ 0x4ce911b4f85da500,0x3f9a62c78b2ed673,0x4ce911b4f85da500,0x3f9a62c78b2ed673,
+ 0xf9ca6556af9c3300,0xc6f55a6990a30c3f,0xf9ca6556af9c3300,0xc6f55a6990a30c3f,
+ 0x4e9865b3fd2bd600,0xc412ef3977a15c8a,0x4e9865b3fd2bd600,0xc412ef3977a15c8a,
+ 0x4677625315243100,0xf0c1d4e5a39287b6,0x4677625315243100,0xf0c1d4e5a39287b6,
+ 0x2e601d537d334e00,0x86c8b5fbd59be6a8,0x2e601d537d334e00,0x86c8b5fbd59be6a8,
+ 0x44c455d591118000,0x890998185cdc4dcd,0x44c455d591118000,0x890998185cdc4dcd,
+ 0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4,0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4,
+ 0x2167561031774600,0x442733514526325,0x2167561031774600,0x442733514526325,
+ 0xf371078576f48200,0xe8cfa788b097ffd,0xf371078576f48200,0xe8cfa788b097ffd,
+ 0xa719912f8836be00,0x843ab20cab159d23,0xa719912f8836be00,0x843ab20cab159d23,
+ 0x89c5115dd4984c00,0xb5f92d61e8a4703c,0x89c5115dd4984c00,0xb5f92d61e8a4703c,
+ 0x50cce47828b49c00,0xd44860fcac301884,0x50cce47828b49c00,0xd44860fcac301884,
+ 0xa1b1869637271000,0xefffc8d879695e4e,0xa1b1869637271000,0xefffc8d879695e4e,
+ 0x1f3b391d02262400,0x4c686a4e51757753,0x1f3b391d02262400,0x4c686a4e51757753,
+ 0x3237fbfeccc90500,0xbcb9757042478b8e,0x3237fbfeccc90500,0xbcb9757042478b8e,
+ 0x6077d7c7a7b0100,0x2d2c565751502a2b,0x6077d7c7a7b0100,0x2d2c565751502a2b,
+ 0x2e268f87a9a10800,0xfff75e567870d9d1,0x2e268f87a9a10800,0xfff75e567870d9d1,
+ 0x73212e7c0f5d5200,0x72202f7d0e5c5301,0x73212e7c0f5d5200,0x72202f7d0e5c5301,
+ 0x458d38f0b57dc800,0x9951e42c69a114dc,0x458d38f0b57dc800,0x9951e42c69a114dc,
+ 0x7b0bc7b7ccbc7000,0x373bfcfb4c40878,0x7b0bc7b7ccbc7000,0x373bfcfb4c40878,
+ 0x4b148fdf94cb500,0x299c65d0d461982d,0x4b148fdf94cb500,0x299c65d0d461982d,
+ 0xd591145481c5400,0xfbafe7b3beeaa2f6,0xd591145481c5400,0xfbafe7b3beeaa2f6,
+ 0xc32aa34a8960e900,0xc32aa34a8960e900,0xc32aa34a8960e900,0xc32aa34a8960e900,
+ 0x235ab6cfec957900,0x4b32dea784fd1168,0x235ab6cfec957900,0x4b32dea784fd1168,
+ 0xe30eb558bb56ed00,0x43ae15f81bf64da0,0xe30eb558bb56ed00,0x43ae15f81bf64da0,
+ 0x5ddffa7825a78200,0xf67451d38e0c29ab,0x5ddffa7825a78200,0xf67451d38e0c29ab,
+ 0x9b96dad74c410d00,0xd004c41dad79b96,0x9b96dad74c410d00,0xd004c41dad79b96,
+ 0xf0965432c2a46600,0x4e28ea8c7c1ad8be,0xf0965432c2a46600,0x4e28ea8c7c1ad8be,
+ 0xfcb5b1f8044d4900,0x95dcd8916d242069,0xfcb5b1f8044d4900,0x95dcd8916d242069,
+ 0x5d24ef96cbb27900,0xa8d11a633e478cf5,0x5d24ef96cbb27900,0xa8d11a633e478cf5,
+ 0xfae6839f65791c00,0x504c2935cfd3b6aa,0xfae6839f65791c00,0x504c2935cfd3b6aa,
+ 0xab0ef257fc59a500,0x4aef13b61db844e1,0xab0ef257fc59a500,0x4aef13b61db844e1,
+ 0x12bd3f90822daf00,0xe946c46b79d654fb,0x12bd3f90822daf00,0xe946c46b79d654fb,
+ 0x4dbe23d39e6df00,0xf62910cfcb142df2,0x4dbe23d39e6df00,0xf62910cfcb142df2,
+ 0xe3abb8f81b53400,0x6d59d8ece2d65763,0xe3abb8f81b53400,0x6d59d8ece2d65763,
+ 0xeaf6f9e50f131c00,0x839f908c667a7569,0xeaf6f9e50f131c00,0x839f908c667a7569,
+ 0xe171f06081119000,0x4ada5bcb2aba3bab,0xe171f06081119000,0x4ada5bcb2aba3bab,
+ 0x9d95838b161e0800,0x848c9a920f071119,0x9d95838b161e0800,0x848c9a920f071119,
+ 0xbc5e24c67a98e200,0xd4364cae12f08a68,0xbc5e24c67a98e200,0xd4364cae12f08a68,
+ 0x2e7833654b1d5600,0x30662d7b5503481e,0x2e7833654b1d5600,0x30662d7b5503481e,
+ 0xf9e1e0f801191800,0xa9b1b0a851494850,0xf9e1e0f801191800,0xa9b1b0a851494850,
+ 0x6177b6a6c7d1100,0xeffe92838594f8e9,0x6177b6a6c7d1100,0xeffe92838594f8e9,
+ 0x6bf9a93b50c29200,0x8c1e4edcb72575e7,0x6bf9a93b50c29200,0x8c1e4edcb72575e7,
+ 0x7ed997304ee9a700,0x3b9cd2750bace245,0x7ed997304ee9a700,0x3b9cd2750bace245,
+ 0x58bf1bfca443e700,0x9f78dc3b638420c7,0x58bf1bfca443e700,0x9f78dc3b638420c7,
+ 0x13ea34cdde27f900,0xfd04da2330c917ee,0x13ea34cdde27f900,0xfd04da2330c917ee,
+ 0xd2eba39a48713900,0xa198d0e93b024a73,0xd2eba39a48713900,0xa198d0e93b024a73,
+ 0xd3a284f526577100,0xb0c1e79645341263,0xd3a284f526577100,0xb0c1e79645341263,
+ 0x891e05921b8c9700,0x83140f9811869d0a,0x891e05921b8c9700,0x83140f9811869d0a,
+ 0x1fa33c809f23bc00,0xb30f902c338f10ac,0x1fa33c809f23bc00,0xb30f902c338f10ac,
+ 0x2542cbac89ee6700,0x166ef88adca4324,0x2542cbac89ee6700,0x166ef88adca4324,
+ 0x15342b0a1f3e2100,0x86a7b8998cadb293,0x15342b0a1f3e2100,0x86a7b8998cadb293,
+ 0x32d05bb98b69e200,0xfc1e957745a72cce,0x32d05bb98b69e200,0xfc1e957745a72cce,
+ 0xed3ffc2ec311d200,0x2bf93ae805d714c6,0xed3ffc2ec311d200,0x2bf93ae805d714c6,
+ 0x5b3f64643f5b00,0xf2a9cd9696cda9f2,0x5b3f64643f5b00,0xf2a9cd9696cda9f2,
+ 0xb18885bc0d343900,0x774e437acbf2ffc6,0xb18885bc0d343900,0x774e437acbf2ffc6,
+ 0x7a1f41245e3b6500,0x9affa1c4bedb85e0,0x7a1f41245e3b6500,0x9affa1c4bedb85e0,
+ 0x11aa0db6a71cbb00,0x2893348f9e258239,0x11aa0db6a71cbb00,0x2893348f9e258239,
+ 0x2defad6f4280c200,0xc90b498ba66426e4,0x2defad6f4280c200,0xc90b498ba66426e4,
+ 0x5e51fdf2aca30f00,0x6768c4cb959a3639,0x5e51fdf2aca30f00,0x6768c4cb959a3639,
+ 0xded84b4d93950600,0x2721b2b46a6cfff9,0xded84b4d93950600,0x2721b2b46a6cfff9,
+ 0xad54c33a976ef900,0x1ce5728b26df48b1,0xad54c33a976ef900,0x1ce5728b26df48b1,
+ 0xb6f1d99e286f4700,0x82c5edaa1c5b7334,0xb6f1d99e286f4700,0x82c5edaa1c5b7334,
+ 0x3681cb7c4afdb700,0x3285cf784ef9b304,0x3681cb7c4afdb700,0x3285cf784ef9b304,
+ 0x9f3e51f06fcea100,0xa1006fce51f09f3e,0x9f3e51f06fcea100,0xa1006fce51f09f3e,
+ 0x9288a2b82a301a00,0x415b716bf9e3c9d3,0x9288a2b82a301a00,0x415b716bf9e3c9d3,
+ 0x7b072458235f7c00,0x770b28542f53700c,0x7b072458235f7c00,0x770b28542f53700c,
+ 0xd7da6e63b4b90d00,0x808d3934e3ee5a57,0xd7da6e63b4b90d00,0x808d3934e3ee5a57,
+ 0x2b9b40f0db6bb00,0xb40f02b9bb000db6,0x2b9b40f0db6bb00,0xb40f02b9bb000db6,
+ 0x32264b5f6d791400,0x1d09647042563b2f,0x32264b5f6d791400,0x1d09647042563b2f,
+ 0x8803cb4bc348800,0x2ba31f979f17ab23,0x8803cb4bc348800,0x2ba31f979f17ab23,
+ 0x58ea49fba311b200,0xa91bb80a52e043f1,0x58ea49fba311b200,0xa91bb80a52e043f1,
+ 0xb0698c55e53cd900,0x3fe603da6ab3568f,0xb0698c55e53cd900,0x3fe603da6ab3568f,
+ 0x2178376e4f165900,0xe7bef1a889d09fc6,0x2178376e4f165900,0xe7bef1a889d09fc6,
+ 0xb141a959e818f000,0xb848a050e111f909,0xb141a959e818f000,0xb848a050e111f909,
+ 0x5d951cd48941c800,0xd81099510cc44d85,0x5d951cd48941c800,0xd81099510cc44d85,
+ 0xa21d7dc260dfbf00,0x69d6b609ab1474cb,0xa21d7dc260dfbf00,0x69d6b609ab1474cb,
+ 0x23ba3ea7841d9900,0xac35b1280b92168f,0x23ba3ea7841d9900,0xac35b1280b92168f,
+ 0x56e9912e78c7bf00,0xeb1c976209fe758,0x56e9912e78c7bf00,0xeb1c976209fe758,
+ 0xc60ce228ee24ca00,0xe329c70dcb01ef25,0xc60ce228ee24ca00,0xe329c70dcb01ef25,
+ 0xef8a2d48a7c26500,0x97f25530dfba1d78,0xef8a2d48a7c26500,0x97f25530dfba1d78,
+ 0x46ab18f5b35eed00,0xa64bf81553be0de0,0x46ab18f5b35eed00,0xa64bf81553be0de0,
+ 0xe67f54cd2bb29900,0x930a21b85ec7ec75,0xe67f54cd2bb29900,0x930a21b85ec7ec75,
+ 0xf01cde32c22eec00,0x40ac6e82729e5cb0,0xf01cde32c22eec00,0x40ac6e82729e5cb0,
+ 0xd612cb0fd91dc400,0xdb1fc602d410c90d,0xd612cb0fd91dc400,0xdb1fc602d410c90d,
+ 0x885f69be36e1d700,0xaf784e9911c6f027,0x885f69be36e1d700,0xaf784e9911c6f027,
+ 0xa1b05544e5f41100,0x6b7a9f8e2f3edbca,0xa1b05544e5f41100,0x6b7a9f8e2f3edbca,
+ 0x3e126448765a2c00,0x8ba7d1fdc3ef99b5,0x3e126448765a2c00,0x8ba7d1fdc3ef99b5,
+ 0x4ebb1beea055f500,0xc03595602edb7b8e,0x4ebb1beea055f500,0xc03595602edb7b8e,
+ 0xcbfbaa9a51613000,0xae9ecfff34045565,0xcbfbaa9a51613000,0xae9ecfff34045565,
+ 0x6e970ff69861f900,0xe41d857c12eb738a,0x6e970ff69861f900,0xe41d857c12eb738a,
+ 0x94dbaae5713e4f00,0x216e1f50c48bfab5,0x94dbaae5713e4f00,0x216e1f50c48bfab5,
+ 0x2ad4be406a94fe00,0xbb452fd1fb056f91,0x2ad4be406a94fe00,0xbb452fd1fb056f91,
+ 0x84c7783bbffc4300,0x4003bcff7b3887c4,0x84c7783bbffc4300,0x4003bcff7b3887c4,
+ 0x508969b9e930d00,0x505dc3cecbc65855,0x508969b9e930d00,0x505dc3cecbc65855,
+ 0xe85a4ffd15a7b200,0xbf0d18aa42f0e557,0xe85a4ffd15a7b200,0xbf0d18aa42f0e557,
+ 0x16739df8ee8b6500,0xa8cd23465035dbbe,0x16739df8ee8b6500,0xa8cd23465035dbbe,
+ 0x175594d6c1834200,0x6f2decaeb9fb3a78,0x175594d6c1834200,0x6f2decaeb9fb3a78,
+ 0xee901f618ff17e00,0x5b25aad43a44cbb5,0xee901f618ff17e00,0x5b25aad43a44cbb5,
+ 0x98a65c62fac43e00,0x221ce6d8407e84ba,0x98a65c62fac43e00,0x221ce6d8407e84ba,
+ 0x10f32ac9d93ae300,0x4e73eddcd2ef714,0x10f32ac9d93ae300,0x4e73eddcd2ef714,
+ 0xd31123e132f0c200,0x69ab995b884a78ba,0xd31123e132f0c200,0x69ab995b884a78ba,
+ 0x695daa9ef7c33400,0xb28671452c18efdb,0x695daa9ef7c33400,0xb28671452c18efdb,
+ 0xffb5cf857a304a00,0xeea4de946b215b11,0xffb5cf857a304a00,0xeea4de946b215b11,
+ 0xfd08aa5fa257f500,0x9065c732cf3a986d,0xfd08aa5fa257f500,0x9065c732cf3a986d,
+ 0xce604be52b85ae00,0xd17f54fa349ab11f,0xce604be52b85ae00,0xd17f54fa349ab11f,
+ 0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf,0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf,
+ 0x9b4a66b72cfdd100,0x3cedc1108b5a76a7,0x9b4a66b72cfdd100,0x3cedc1108b5a76a7,
+ 0x98ab5261f9ca3300,0xdfec1526be8d7447,0x98ab5261f9ca3300,0xdfec1526be8d7447,
+ 0x2ce1bf725e93cd00,0xd71a4489a56836fb,0x2ce1bf725e93cd00,0xd71a4489a56836fb,
+ 0xb6adb4af19021b00,0xc5dec7dc6a716873,0xb6adb4af19021b00,0xc5dec7dc6a716873,
+ 0xa960935af33ac900,0x6ea7549d34fd0ec7,0xa960935af33ac900,0x6ea7549d34fd0ec7,
+ 0xe2a57e39db9c4700,0x8ccb1057b5f2296e,0xe2a57e39db9c4700,0x8ccb1057b5f2296e,
+ 0x357a9ad5e0af4f00,0x1956b6f9cc83632c,0x357a9ad5e0af4f00,0x1956b6f9cc83632c,
+ 0x2583832500a6a600,0xd37575d3f65050f6,0x2583832500a6a600,0xd37575d3f65050f6,
+ 0x6d646f660b020900,0xa6afa4adc0c9c2cb,0x6d646f660b020900,0xa6afa4adc0c9c2cb,
+ 0x8135c672f347b400,0xb105f642c3778430,0x8135c672f347b400,0xb105f642c3778430,
+ 0x4916c29dd48b5f00,0x5a05d18ec7984c13,0x4916c29dd48b5f00,0x5a05d18ec7984c13,
+ 0xa45cfb03a75ff800,0x52aa0df551a90ef6,0xa45cfb03a75ff800,0x52aa0df551a90ef6,
+ 0xcfefdafa35152000,0x14340121eecefbdb,0xcfefdafa35152000,0x14340121eecefbdb,
+ 0xce7c2a9856e4b200,0x7bc99f2de35107b5,0xce7c2a9856e4b200,0x7bc99f2de35107b5,
+ 0xf006e711e117f600,0x996f8e78887e9f69,0xf006e711e117f600,0x996f8e78887e9f69,
+ 0x520b94cd9fc65900,0xcd940b520059c69f,0x520b94cd9fc65900,0xcd940b520059c69f,
+ 0x534ca7b8ebf41f00,0x78678c93c0df342b,0x534ca7b8ebf41f00,0x78678c93c0df342b,
+ 0x7d668b90edf61b00,0x776c819ae7fc110a,0x7d668b90edf61b00,0x776c819ae7fc110a,
+ 0xf2dfcde0123f2d00,0x210c1e33c1ecfed3,0xf2dfcde0123f2d00,0x210c1e33c1ecfed3,
+ 0xfe0a5fab55a1f400,0x6c98cd39c7336692,0xfe0a5fab55a1f400,0x6c98cd39c7336692,
+ 0xb8b26c66ded40a00,0x707aa4ae161cc2c8,0xb8b26c66ded40a00,0x707aa4ae161cc2c8,
+ 0xcfde0e1fd0c11100,0xe5f42435faeb3b2a,0xcfde0e1fd0c11100,0xe5f42435faeb3b2a,
+ 0xa9947b46efd23d00,0x211cf3ce675ab588,0xa9947b46efd23d00,0x211cf3ce675ab588,
+ 0xd96be95b8230b200,0xb80a883ae351d361,0xd96be95b8230b200,0xb80a883ae351d361,
+ 0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce,0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce,
+ 0x9cef790a96e57300,0xd4a73142dead3b48,0x9cef790a96e57300,0xd4a73142dead3b48,
+ 0x9f065ec758c19900,0xd24b138a158cd44d,0x9f065ec758c19900,0xd24b138a158cd44d,
+ 0xfe8d2457a9da7300,0xe291384bb5c66f1c,0xfe8d2457a9da7300,0xe291384bb5c66f1c,
+ 0xd5ef0e34e1db3a00,0x251ffec4112bcaf0,0xd5ef0e34e1db3a00,0x251ffec4112bcaf0,
+ 0x97f61879ee8f6100,0x7e1ff190076688e9,0x97f61879ee8f6100,0x7e1ff190076688e9,
+ 0x4040040444440000,0xf3f3b7b7f7f7b3b3,0x4040040444440000,0xf3f3b7b7f7f7b3b3,
+ 0xa8a7333c949b0f00,0x1817838c242bbfb0,0xa8a7333c949b0f00,0x1817838c242bbfb0,
+ 0x50a34dbeee1df300,0x2cdf31c292618f7c,0x50a34dbeee1df300,0x2cdf31c292618f7c,
+ 0xaebb2c3997821500,0x4055c2d7796cfbee,0xaebb2c3997821500,0x4055c2d7796cfbee,
+ 0x1743d48493c7500,0x97e2abdedfaae396,0x1743d48493c7500,0x97e2abdedfaae396,
+ 0x9b983033a8ab0300,0x8a892122b9ba1211,0x9b983033a8ab0300,0x8a892122b9ba1211,
+ 0x442b026d29466f00,0x4629006f2b446d02,0x442b026d29466f00,0x4629006f2b446d02,
+ 0x2d96d06b46fdbb00,0x8c3771cae75c1aa1,0x2d96d06b46fdbb00,0x8c3771cae75c1aa1,
+ 0x765d466d1b302b00,0x84afb49fe9c2d9f2,0x765d466d1b302b00,0x84afb49fe9c2d9f2,
+ 0xecf94555b9ac100,0x80411adbd5144f8e,0xecf94555b9ac100,0x80411adbd5144f8e,
+ 0xbb354ece75fb800,0x348c6bd3d860873f,0xbb354ece75fb800,0x348c6bd3d860873f,
+ 0xec67840fe3688b00,0xf972911af67d9e15,0xec67840fe3688b00,0xf972911af67d9e15,
+ 0x611f522c4d337e00,0x84fab7c9a8d69be5,0x611f522c4d337e00,0x84fab7c9a8d69be5,
+ 0xf55079dc298ca500,0x49ecc560953019bc,0xf55079dc298ca500,0x49ecc560953019bc,
+ 0xe35845fe1da6bb00,0x10abb60dee5548f3,0xe35845fe1da6bb00,0x10abb60dee5548f3,
+ 0x11a408bdac19b500,0x6bde72c7d663cf7a,0x11a408bdac19b500,0x6bde72c7d663cf7a,
+ 0x3b612f754e145a00,0x9fc58bd1eab0fea4,0x3b612f754e145a00,0x9fc58bd1eab0fea4,
+ 0xf6ff8d84727b0900,0x373e4c45b3bac8c1,0xf6ff8d84727b0900,0x373e4c45b3bac8c1,
+ 0xa7339307a0349400,0x31a5059136a20296,0xa7339307a0349400,0x31a5059136a20296,
+ 0x601d7d00601d7d00,0x4f32522f4f32522f,0x601d7d00601d7d00,0x4f32522f4f32522f,
+ 0xb9d1593188e06800,0x5830b8d0690189e1,0xb9d1593188e06800,0x5830b8d0690189e1,
+ 0x9c7319f66a85ef00,0x937c16f9658ae00f,0x9c7319f66a85ef00,0x937c16f9658ae00f,
+ 0xb769ca14a37dde00,0x27f95a8433ed4e90,0xb769ca14a37dde00,0x27f95a8433ed4e90,
+ 0xc32134d615f7e200,0x9674618340a2b755,0xc32134d615f7e200,0x9674618340a2b755,
+ 0x4e6c6a4806242200,0x391b1d3f71535577,0x4e6c6a4806242200,0x391b1d3f71535577,
+ 0x68312f761e475900,0xb9e0fea7cf9688d1,0x68312f761e475900,0xb9e0fea7cf9688d1,
+ 0xd30571a774a2d600,0x9c4a3ee83bed994f,0xd30571a774a2d600,0x9c4a3ee83bed994f,
+ 0x8990dfc64f561900,0x7e672831b8a1eef7,0x8990dfc64f561900,0x7e672831b8a1eef7,
+ 0x2023a2a181820300,0xbfbc3d3e1e1d9c9f,0x2023a2a181820300,0xbfbc3d3e1e1d9c9f,
+ 0xe26956dd3fb48b00,0xac27189371fac54e,0xe26956dd3fb48b00,0xac27189371fac54e,
+ 0xd95f2ea871f78600,0x66e09117ce4839bf,0xd95f2ea871f78600,0x66e09117ce4839bf,
+ 0x159d76feeb638800,0x1d957ef6e36b8008,0x159d76feeb638800,0x1d957ef6e36b8008,
+ 0xebebc3c328280000,0x24240c0ce7e7cfcf,0xebebc3c328280000,0x24240c0ce7e7cfcf,
+ 0x95ba022db8972f00,0x3f10a887123d85aa,0x95ba022db8972f00,0x3f10a887123d85aa,
+ 0x4a53554c061f1900,0xd3caccd59f868099,0x4a53554c061f1900,0xd3caccd59f868099,
+ 0xebd3f6ce251d3800,0xb189ac947f47625a,0xebd3f6ce251d3800,0xb189ac947f47625a,
+ 0x7db9e92d5094c400,0xc1055591ec2878bc,0x7db9e92d5094c400,0xc1055591ec2878bc,
+ 0x6ac00aaac06aa00,0x4de74be1e74de14b,0x6ac00aaac06aa00,0x4de74be1e74de14b,
+ 0x37669fcef9a85100,0xd4857c2d1a4bb2e3,0x37669fcef9a85100,0xd4857c2d1a4bb2e3,
+ 0xd618c00ed816ce00,0x3af42ce234fa22ec,0xd618c00ed816ce00,0x3af42ce234fa22ec,
+ 0x22cd739cbe51ef00,0x9a75cb2406e957b8,0x22cd739cbe51ef00,0x9a75cb2406e957b8,
+ 0xa2b64652f0e41400,0x617585913327d7c3,0xa2b64652f0e41400,0x617585913327d7c3,
+ 0x3c0de1d1eddc300,0xb47769aaa96a74b7,0x3c0de1d1eddc300,0xb47769aaa96a74b7,
+ 0xaa771dcd67bad00,0x2c8157faf05d8b26,0xaa771dcd67bad00,0x2c8157faf05d8b26,
+ 0x870aa429ae238d00,0x61ec42cf48c56be6,0x870aa429ae238d00,0x61ec42cf48c56be6,
+ 0x5ae3b90953eab00,0xca61f45f5af164cf,0x5ae3b90953eab00,0xca61f45f5af164cf,
+ 0xbc215bc67ae79d00,0xf16c168b37aad04d,0xbc215bc67ae79d00,0xf16c168b37aad04d,
+ 0x4cd01b87cb579c00,0xc458930f43df1488,0x4cd01b87cb579c00,0xc458930f43df1488,
+ 0x7405651460117100,0xfd8cec9de998f889,0x7405651460117100,0xfd8cec9de998f889,
+ 0xf812d832ca20ea00,0x816ba14bb3599379,0xf812d832ca20ea00,0x816ba14bb3599379,
+ 0xdf7c53f02f8ca300,0xf55679da05a6892a,0xdf7c53f02f8ca300,0xf55679da05a6892a,
+ 0x16685e2036487e00,0x57b4d33255b6d13,0x16685e2036487e00,0x57b4d33255b6d13,
+ 0x4d24e78ec3aa6900,0x69aac38ee7244d,0x4d24e78ec3aa6900,0x69aac38ee7244d,
+ 0xf4853c4db9c87100,0x413089f80c7dc4b5,0xf4853c4db9c87100,0x413089f80c7dc4b5,
+ 0x237a451c3f665900,0xecb58ad3f0a996cf,0x237a451c3f665900,0xecb58ad3f0a996cf,
+ 0x5206b4e4b6e2500,0x83a6edc8cde8a386,0x5206b4e4b6e2500,0x83a6edc8cde8a386,
+ 0x434358581b1b0000,0xacacb7b7f4f4efef,0x434358581b1b0000,0xacacb7b7f4f4efef,
+ 0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc,0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc,
+ 0x5825a7da82ff7d00,0x88f5770a522fadd0,0x5825a7da82ff7d00,0x88f5770a522fadd0,
+ 0x26fb7da0865bdd00,0x7ea325f8de038558,0x26fb7da0865bdd00,0x7ea325f8de038558,
+ 0x133c002f3c132f00,0xecc3ffd0c3ecd0ff,0x133c002f3c132f00,0xecc3ffd0c3ecd0ff,
+ 0x8aa97556dcff2300,0xb695496ae0c31f3c,0x8aa97556dcff2300,0xb695496ae0c31f3c,
+ 0x7d067b0b760d700,0x7aad1acdca1daa7d,0x7d067b0b760d700,0x7aad1acdca1daa7d,
+ 0xb0c3e49727547300,0xc5b691e252210675,0xb0c3e49727547300,0xc5b691e252210675,
+ 0x420cc789cb854e00,0x622ce7a9eba56e20,0x420cc789cb854e00,0x622ce7a9eba56e20,
+ 0x4d3abbcc81f67700,0x5225a4d39ee9681f,0x4d3abbcc81f67700,0x5225a4d39ee9681f,
+ 0x5192e32071b2c300,0xbe7d0ccf9e5d2cef,0x5192e32071b2c300,0xbe7d0ccf9e5d2cef,
+ 0x3b7482cdf6b94f00,0xca85733c0748bef1,0x3b7482cdf6b94f00,0xca85733c0748bef1,
+ 0xfb451ca259e7be00,0xb00e57e912acf54b,0xfb451ca259e7be00,0xb00e57e912acf54b,
+ 0x8f1ee372fd6c9100,0x9809f465ea7b8617,0x8f1ee372fd6c9100,0x9809f465ea7b8617,
+ 0x7784956611e2f300,0xa85b4ab9ce3d2cdf,0x7784956611e2f300,0xa85b4ab9ce3d2cdf,
+ 0xc0de5e4e8e90100,0xa0be3e2eeef0706,0xc0de5e4e8e90100,0xa0be3e2eeef0706,
+ 0xe92b8644ad6fc200,0x5a9835f71edc71b3,0xe92b8644ad6fc200,0x5a9835f71edc71b3,
+ 0x67256b294e0c4200,0xda98d694f3b1ffbd,0x67256b294e0c4200,0xda98d694f3b1ffbd,
+ 0xc7dd4a5a9d87100,0xd3a20b7a7607aedf,0xc7dd4a5a9d87100,0xd3a20b7a7607aedf,
+ 0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620,0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620,
+ 0x2b73fba388d05800,0xc79f174f643cb4ec,0x2b73fba388d05800,0xc79f174f643cb4ec,
+ 0xbe91022d93bc2f00,0xa38c1f308ea1321d,0xbe91022d93bc2f00,0xa38c1f308ea1321d,
+ 0x79e622bdc45b9f00,0xb926e27d049b5fc0,0x79e622bdc45b9f00,0xb926e27d049b5fc0,
+ };
+
+
+
+}
+
diff --git a/bitpolymul/trunc_btfy_tab_64.h b/bitpolymul/trunc_btfy_tab_64.h
new file mode 100644
index 0000000..1082cca
--- /dev/null
+++ b/bitpolymul/trunc_btfy_tab_64.h
@@ -0,0 +1,294 @@
+#pragma once
+/*
+Copyright (C) 2017 Ming-Shing Chen
+
+This file is part of BitPolyMul.
+
+BitPolyMul is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+BitPolyMul is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with BitPolyMul. If not, see .
+*/
+
+
+
+#include "stdint.h"
+
+
+namespace bpm {
+
+
+
+ alignas(32) const uint64_t i_beta_mul_32_bm4r[(64 / 4) * 16 * 2] = {
+ 0x100c7c6c7c60100,0x405c2c3c2c30405, 0x100c7c6c7c60100,0x405c2c3c2c30405,
+ 0x9d6863960bfef500,0xfb0e05f06d989366, 0x9d6863960bfef500,0xfb0e05f06d989366,
+ 0xe1e15e5ebfbf0000,0xa0a01f1ffefe4141, 0xe1e15e5ebfbf0000,0xa0a01f1ffefe4141,
+ 0x44ae6288cc26ea00,0x45af6389cd27eb01, 0x44ae6288cc26ea00,0x45af6389cd27eb01,
+ 0xa5a5e4e441410000,0xe5e5a4a401014040, 0xa5a5e4e441410000,0xe5e5a4a401014040,
+ 0x1a1598978d820f00,0xa5aa2728323db0bf, 0x1a1598978d820f00,0xa5aa2728323db0bf,
+ 0x7e7e060678780000,0xaeaed6d6a8a8d0d0, 0x7e7e060678780000,0xaeaed6d6a8a8d0d0,
+ 0xd44337a074e39700,0x6afd891eca5d29be, 0xd44337a074e39700,0x6afd891eca5d29be,
+ 0xe9e963638a8a0000,0x80800a0ae3e36969, 0xe9e963638a8a0000,0x80800a0ae3e36969,
+ 0xc46115b571d4a00,0x2f653278743e6923, 0xc46115b571d4a00,0x2f653278743e6923,
+ 0xc7c7dcdc1b1b0000,0xe3e3f8f83f3f2424, 0xc7c7dcdc1b1b0000,0xe3e3f8f83f3f2424,
+ 0xf41f678c7893eb00,0x4ca7df34c02b53b8, 0xf41f678c7893eb00,0x4ca7df34c02b53b8,
+ 0xc0c0565696960000,0xf3f36565a5a53333, 0xc0c0565696960000,0xf3f36565a5a53333,
+ 0x3b2bafbf84941000,0xd9c94d5d6676f2e2, 0x3b2bafbf84941000,0xd9c94d5d6676f2e2,
+ 0xf5f5fdfd08080000,0x82828a8a7f7f7777, 0xf5f5fdfd08080000,0x82828a8a7f7f7777,
+ 0x1fce83524d9cd100,0xa3723feef1206dbc, 0x1fce83524d9cd100,0xa3723feef1206dbc,
+ 0x4e0f9edf91d04100,0xe6a736773978e9a8, 0x4e0f9edf91d04100,0xe6a736773978e9a8,
+ 0x8f69e606896fe00,0x946a02fcf40a629c, 0x8f69e606896fe00,0x946a02fcf40a629c,
+ 0x7bf5e36d16988e00,0x1d93850b70fee866, 0x7bf5e36d16988e00,0x1d93850b70fee866,
+ 0x42a1ad4e0cefe300,0x7e4e80b49aaa645, 0x42a1ad4e0cefe300,0x7e4e80b49aaa645,
+ 0xea6b5cdd37b68100,0x1998af2ec44572f3, 0xea6b5cdd37b68100,0x1998af2ec44572f3,
+ 0x1caa8f392593b600,0x3482a7110dbb9e28, 0x1caa8f392593b600,0x3482a7110dbb9e28,
+ 0xc39ef6ab68355d00,0x421f772ae9b4dc81, 0xc39ef6ab68355d00,0x421f772ae9b4dc81,
+ 0x2af3b069439ad900,0x29f0b36a4099da03, 0x2af3b069439ad900,0x29f0b36a4099da03,
+ 0x3853f19aa2c96b00,0x3c57f59ea6cd6f04, 0x3853f19aa2c96b00,0x3c57f59ea6cd6f04,
+ 0x8cf85e2aa6d27400,0xf5812753dfab0d79, 0x8cf85e2aa6d27400,0xf5812753dfab0d79,
+ 0x9ca9083da1943500,0xb3e9faa3603a297, 0x9ca9083da1943500,0xb3e9faa3603a297,
+ 0xadddc9b914647000,0xa9d9cdbd10607404, 0xadddc9b914647000,0xa9d9cdbd10607404,
+ 0x3fcc44b7887bf300,0x4ab931c2fd0e8675, 0x3fcc44b7887bf300,0x4ab931c2fd0e8675,
+ 0x3e01e5dae4db3f00,0xbe81655a645bbf80, 0x3e01e5dae4db3f00,0xbe81655a645bbf80,
+ 0xd8a2c6bc641e7a00,0x87fd99e33b41255f, 0xd8a2c6bc641e7a00,0x87fd99e33b41255f,
+ 0xc073ea59992ab300,0xfc4fd665a5168f3c, 0xc073ea59992ab300,0xfc4fd665a5168f3c,
+ 0x4346484d0e0b0500,0xfafff1f4b7b2bcb9, 0x4346484d0e0b0500,0xfafff1f4b7b2bcb9,
+ 0x40b6e11757a1f600,0x7c8add2b6b9dca3c, 0x40b6e11757a1f600,0x7c8add2b6b9dca3c,
+ 0x7a47764b310c3d00,0x320f3e0379447548, 0x7a47764b310c3d00,0x320f3e0379447548,
+ 0xba3c8b0db7318600,0x29af189e24a21593, 0xba3c8b0db7318600,0x29af189e24a21593,
+ 0x41eb1fb5f45eaa00,0xcb61953f7ed4208a, 0x41eb1fb5f45eaa00,0xcb61953f7ed4208a,
+ 0x1a73335a40296900,0x771e5e372d44046d, 0x1a73335a40296900,0x771e5e372d44046d,
+ 0xcc01a16ca06dcd00,0xf23f9f529e53f33e, 0xcc01a16ca06dcd00,0xf23f9f529e53f33e,
+ 0xa3b74753f0e41400,0xe3f70713b0a45440, 0xa3b74753f0e41400,0xe3f70713b0a45440,
+ 0x94954342d6d70100,0x6d6cbabb2f2ef8f9, 0x94954342d6d70100,0x6d6cbabb2f2ef8f9,
+ 0x51fa0aa1f05bab00,0xcb60903b6ac1319a, 0x51fa0aa1f05bab00,0xcb60903b6ac1319a,
+ 0x5252dddd8f8f0000,0xfafa75752727a8a8, 0x5252dddd8f8f0000,0xfafa75752727a8a8,
+ 0x1b418ed4cf955a00,0x540ec19b80da154f, 0x1b418ed4cf955a00,0x540ec19b80da154f,
+ 0xb27901ca78b3cb00,0xf03b43883af18942, 0xb27901ca78b3cb00,0xf03b43883af18942,
+ 0x13a143f1e250b200,0x45f715a7b406e456, 0x13a143f1e250b200,0x45f715a7b406e456,
+ 0x9d3006ab369bad00,0x6dc0f65bc66b5df0, 0x9d3006ab369bad00,0x6dc0f65bc66b5df0,
+ 0x3b7cdc9ba0e74700,0xaaed4d0a3176d691, 0x3b7cdc9ba0e74700,0xaaed4d0a3176d691,
+ 0x61cb3c96f75daa00,0x1ab047ed8c26d17b, 0x61cb3c96f75daa00,0x1ab047ed8c26d17b,
+ 0x60ad0bc6a66bcd00,0x9459ff32529f39f4, 0x60ad0bc6a66bcd00,0x9459ff32529f39f4,
+ 0x8db76953dee43a00,0x271dc3f9744e90aa, 0x8db76953dee43a00,0x271dc3f9744e90aa,
+ 0x7d17f09ae78d6a00,0x16b8ce69bf1167c, 0x7d17f09ae78d6a00,0x16b8ce69bf1167c,
+ 0x4192c5165784d300,0x1ac99e4d0cdf885b, 0x4192c5165784d300,0x1ac99e4d0cdf885b,
+ 0x50c2bc2e7eec9200,0x92ec7e2ebcc250, 0x50c2bc2e7eec9200,0x92ec7e2ebcc250,
+ 0x3f7da1e3dc9e4200,0x3072aeecd3914d0f, 0x3f7da1e3dc9e4200,0x3072aeecd3914d0f,
+ 0x2be3834b60a8c800,0x25ed8d456ea6c60e, 0x2be3834b60a8c800,0x25ed8d456ea6c60e,
+ 0xeea52b608ec54b00,0x4e058bc02e65eba0, 0xeea52b608ec54b00,0x4e058bc02e65eba0,
+ 0xa8f3aef55d065b00,0x89d28fd47c277a21, 0xa8f3aef55d065b00,0x89d28fd47c277a21,
+ 0x91b4a38617322500,0x80a5b29706233411, 0x91b4a38617322500,0x80a5b29706233411,
+ 0x91f897fe6f066900,0xec85ea83127b147d, 0x91f897fe6f066900,0xec85ea83127b147d,
+ 0xcd1ed201cc1fd300,0x34e72bf835e62af9, 0xcd1ed201cc1fd300,0x34e72bf835e62af9,
+ 0xf5ad346c99c15800,0xf5ad346c99c15800, 0xf5ad346c99c15800,0xf5ad346c99c15800,
+ 0x994724fa63bdde00,0x3be58658c11f7ca2, 0x994724fa63bdde00,0x3be58658c11f7ca2,
+ 0xaf46678e21c8e900,0x27ceef06a9406188, 0xaf46678e21c8e900,0x27ceef06a9406188,
+ 0x60f7de4929be9700,0x26b1980f6ff8d146, 0x60f7de4929be9700,0x26b1980f6ff8d146,
+ 0x4e3df383cdbe700,0xa1467a9d997e42a5, 0x4e3df383cdbe700,0xa1467a9d997e42a5,
+ 0x3fbc27a49b188300,0xb231aa2916950e8d, 0x3fbc27a49b188300,0xb231aa2916950e8d,
+ 0x1b367558436e2d00,0x9fb2f1dcc7eaa984, 0x1b367558436e2d00,0x9fb2f1dcc7eaa984,
+ 0xd773258156f2a400,0xa50157f32480d672, 0xd773258156f2a400,0xa50157f32480d672,
+ 0xc616a171b767d000,0x4f9f28f83eee5989, 0xc616a171b767d000,0x4f9f28f83eee5989,
+ 0x3bada2340f999600,0x6cfaf56358cec157, 0x3bada2340f999600,0x6cfaf56358cec157,
+ 0x54e03f8bdf6bb400,0x9420ff4b1fab74c0, 0x54e03f8bdf6bb400,0x9420ff4b1fab74c0,
+ 0x25b24fd8fd6a9700,0x6cfb0691b423de49, 0x25b24fd8fd6a9700,0x6cfb0691b423de49,
+ 0x11e685726394f700,0x936407f0e1167582, 0x11e685726394f700,0x936407f0e1167582,
+ 0xd942ba21f8639b00,0x811ae279a03bc358, 0xd942ba21f8639b00,0x811ae279a03bc358,
+ 0xad6d67a70acac000,0xa96963a30ecec404, 0xad6d67a70acac000,0xa96963a30ecec404,
+ 0xcd6510b875dda800,0xf45c29814ce49139, 0xcd6510b875dda800,0xf45c29814ce49139,
+ 0x7daae235489fd700,0x92450ddaa77038ef, 0x7daae235489fd700,0x92450ddaa77038ef,
+ 0x70676b7c0c1b1700,0x8f989483f3e4e8ff, 0x70676b7c0c1b1700,0x8f989483f3e4e8ff,
+ 0xb925ce52eb779c00,0xc955be229b07ec70, 0xb925ce52eb779c00,0xc955be229b07ec70,
+ 0x209e3e8eae10b00,0xb4bf555e5c57bdb6, 0x209e3e8eae10b00,0xb4bf555e5c57bdb6,
+ 0x65792c3c5945100,0x85d411404617d283, 0x65792c3c5945100,0x85d411404617d283,
+ 0xcadf2a3ff5e01500,0x411e4f13b2edbce, 0xcadf2a3ff5e01500,0x411e4f13b2edbce,
+ 0x8a14af31bb259e00,0xcc52e977fd63d846, 0x8a14af31bb259e00,0xcc52e977fd63d846,
+ 0x63d67cc9aa1fb500,0xab1eb40162d77dc8, 0x63d67cc9aa1fb500,0xab1eb40162d77dc8,
+ 0x87f81966e19e7f00,0xc4bb5a25a2dd3c43, 0x87f81966e19e7f00,0xc4bb5a25a2dd3c43,
+ 0xbb59be5ce705e200,0xae80fed56b453b1, 0xbb59be5ce705e200,0xae80fed56b453b1,
+ 0x3137040233350600,0x696f5c5a6b6d5e58, 0x3137040233350600,0x696f5c5a6b6d5e58,
+ 0x3e8168d7e956bf00,0x219e77c8f649a01f, 0x3e8168d7e956bf00,0x219e77c8f649a01f,
+ 0xb3ca1d64d7ae7900,0x2a5384fd4e37e099, 0xb3ca1d64d7ae7900,0x2a5384fd4e37e099,
+ 0xd6eba5984e733d00,0x38054b76a09dd3ee, 0xd6eba5984e733d00,0x38054b76a09dd3ee,
+ 0xcdcd6868a5a50000,0x1818bdbd7070d5d5, 0xcdcd6868a5a50000,0x1818bdbd7070d5d5,
+ 0x362a405c6a761c00,0x130f65794f533925, 0x362a405c6a761c00,0x130f65794f533925,
+ 0x3b0ad9e8d3e23100,0x774695a49fae7d4c, 0x3b0ad9e8d3e23100,0x774695a49fae7d4c,
+ 0x4ef5a01b55eebb00,0x2b9ec5719a2f74c, 0x4ef5a01b55eebb00,0x2b9ec5719a2f74c,
+ 0xf344b80ffc4bb700,0xa81fe354a710ec5b, 0xf344b80ffc4bb700,0xa81fe354a710ec5b,
+ 0xa0d9d9a90970700,0x6166f6f1fbfc6c6b, 0xa0d9d9a90970700,0x6166f6f1fbfc6c6b,
+ 0xec0c3cdc30d0e000,0x47a797779b7b4bab, 0xec0c3cdc30d0e000,0x47a797779b7b4bab,
+ 0x27a07ef9de598700,0xa720fe795ed90780, 0x27a07ef9de598700,0xa720fe795ed90780,
+ 0x6620abed8bcd4600,0x296fe4a2c482094f, 0x6620abed8bcd4600,0x296fe4a2c482094f,
+ 0x50d42aaefe7a8400,0x3eba44c09014ea6e, 0x50d42aaefe7a8400,0x3eba44c09014ea6e,
+ 0x27499efed9b7600,0xe0967b0d0f7994e2, 0x27499efed9b7600,0xe0967b0d0f7994e2,
+ 0x55cf3fa5f06a9a00,0x940efe6431ab5bc1, 0x55cf3fa5f06a9a00,0x940efe6431ab5bc1,
+ 0xb2fde8a7155a4f00,0x7936236cde9184cb, 0xb2fde8a7155a4f00,0x7936236cde9184cb,
+ 0x683b5300683b5300,0x4211792a4211792a, 0x683b5300683b5300,0x4211792a4211792a,
+ 0x2b504b301b607b00,0xf48f94efc4bfa4df, 0x2b504b301b607b00,0xf48f94efc4bfa4df,
+ 0x982a49fb63d1b200,0xbe0c6fdd45f79426, 0x982a49fb63d1b200,0xbe0c6fdd45f79426,
+ 0x4604246620624200,0xb5f7d795d391b1f3, 0x4604246620624200,0xb5f7d795d391b1f3,
+ 0xd88888d800505000,0x65353565bdededbd, 0xd88888d800505000,0x65353565bdededbd,
+ 0xd7f62504d3f22100,0xbe9f4c6dba9b4869, 0xd7f62504d3f22100,0xbe9f4c6dba9b4869,
+ 0xf4119a7f8b6ee500,0x39dc57b246a328cd, 0xf4119a7f8b6ee500,0x39dc57b246a328cd,
+ 0x1cdccb0b17d7c000,0xb47463a3bf7f68a8, 0x1cdccb0b17d7c000,0xb47463a3bf7f68a8,
+ 0x62bc6fb1d30dde00,0x4da09d7b56bb866, 0x62bc6fb1d30dde00,0x4da09d7b56bb866,
+ 0x83bbf9c1427a3800,0xf7cf8db5360e4c74, 0x83bbf9c1427a3800,0xf7cf8db5360e4c74,
+ 0x289915a48c3db100,0xca7bf7466edf53e2, 0x289915a48c3db100,0xca7bf7466edf53e2,
+ 0x3d6f085a67355200,0xe1b3d486bbe98edc, 0x3d6f085a67355200,0xe1b3d486bbe98edc,
+ 0x44adea0347aee900,0x34dd9a7337de9970, 0x44adea0347aee900,0x34dd9a7337de9970,
+ 0x3119163e0f272800,0xe1c9c6eedff7f8d0, 0x3119163e0f272800,0xe1c9c6eedff7f8d0,
+ 0x605b447f1f243b00,0xd3e8f7ccac9788b3, 0x605b447f1f243b00,0xd3e8f7ccac9788b3,
+ 0x963eb41c8a22a800,0xfe56dc74e24ac068, 0x963eb41c8a22a800,0xfe56dc74e24ac068,
+ 0x4577c2f0b5873200,0x7e4cf9cb8ebc093b, 0x4577c2f0b5873200,0x7e4cf9cb8ebc093b,
+ 0x759a917e0be4ef00,0xbe515ab5c02f24cb, 0x759a917e0be4ef00,0xbe515ab5c02f24cb,
+ 0xa5a47171d4d5000,0xa5f5e8b8b2e2ffaf, 0xa5a47171d4d5000,0xa5f5e8b8b2e2ffaf,
+ 0xdfbc7310cfac6300,0x6a09c6a57a19d6b5, 0xdfbc7310cfac6300,0x6a09c6a57a19d6b5,
+ 0x9d9cb4b528290100,0x58597170edecc4c5, 0x9d9cb4b528290100,0x58597170edecc4c5,
+ 0x57a8f7085fa0ff00,0x8c732cd3847b24db, 0x57a8f7085fa0ff00,0x8c732cd3847b24db,
+ 0xeb4bea4aa101a000,0x16b617b75cfc5dfd, 0xeb4bea4aa101a000,0x16b617b75cfc5dfd,
+ 0x1339e8c2d1fb2a00,0xa18b5a70634998b2, 0x1339e8c2d1fb2a00,0xa18b5a70634998b2,
+ };
+
+
+ alignas(32) const uint64_t beta_mul_32_bm4r[(64 / 4) * 16 * 2] = {
+ 0x9796d3d245440100,0x8485c0c156571213, 0x9796d3d245440100,0x8485c0c156571213,
+ 0xe9b9e8b851015000,0x6d3d6c3cd585d484, 0xe9b9e8b851015000,0x6d3d6c3cd585d484,
+ 0xd6d6b4b462620000,0x74741616c0c0a2a2, 0xd6d6b4b462620000,0x74741616c0c0a2a2,
+ 0x679fb1492ed6f800,0xbb436d95f20a24dc, 0x679fb1492ed6f800,0xbb436d95f20a24dc,
+ 0x191914140d0d0000,0x6a6a67677e7e7373, 0x191914140d0d0000,0x6a6a67677e7e7373,
+ 0xd36077c417a4b300,0x5ae9fe4d9e2d3a89, 0xd36077c417a4b300,0x5ae9fe4d9e2d3a89,
+ 0x6363ecec8f8f0000,0xf4f47b7b18189797, 0x6363ecec8f8f0000,0xf4f47b7b18189797,
+ 0x255189fdd8ac7400,0x483ce490b5c1196d, 0x255189fdd8ac7400,0x483ce490b5c1196d,
+ 0x9191e6e677770000,0x52522525b4b4c3c3, 0x9191e6e677770000,0x52522525b4b4c3c3,
+ 0x4c7b3e0945723700,0x427530074b7c390e, 0x4c7b3e0945723700,0x427530074b7c390e,
+ 0xaaaa6464cece0000,0x41418f8f2525ebeb, 0xaaaa6464cece0000,0x41418f8f2525ebeb,
+ 0x813e6dd253ecbf00,0xfd4211ae2f90c37c, 0x813e6dd253ecbf00,0xfd4211ae2f90c37c,
+ 0x3f3f686857570000,0xd2d28585babaeded, 0x3f3f686857570000,0xd2d28585babaeded,
+ 0xe702a643a441e500,0x7d983cd93edb7f9a, 0xe702a643a441e500,0x7d983cd93edb7f9a,
+ 0x5b5bb6b6eded0000,0xc7c72a2a71719c9c, 0x5b5bb6b6eded0000,0xc7c72a2a71719c9c,
+ 0xb7e31d49feaa5400,0xd98d732790c43a6e, 0xb7e31d49feaa5400,0xd98d732790c43a6e,
+ 0x28ea02c2ea28c00,0xd15d73fffd715fd3, 0x28ea02c2ea28c00,0xd15d73fffd715fd3,
+ 0x3ff772ba854dc800,0x30f87db58a42c70f, 0x3ff772ba854dc800,0x30f87db58a42c70f,
+ 0xc7584cd3148b9f00,0x897831cdb4450cf, 0xc7584cd3148b9f00,0x897831cdb4450cf,
+ 0x6ed065dbb50bbe00,0x7bc570cea01eab15, 0x6ed065dbb50bbe00,0x7bc570cea01eab15,
+ 0xf10575817084f400,0xe81c6c98699ded19, 0xf10575817084f400,0xe81c6c98699ded19,
+ 0xd7f80827f0df2f00,0xeac5351acde2123d, 0xd7f80827f0df2f00,0xeac5351acde2123d,
+ 0x8a1b28b933a29100,0xc35261f07aebd849, 0x8a1b28b933a29100,0xc35261f07aebd849,
+ 0x5e847fa5fb21da00,0x62b84399c71de63c, 0x5e847fa5fb21da00,0x62b84399c71de63c,
+ 0xe87745da32ad9f00,0x51cefc638b1426b9, 0xe87745da32ad9f00,0x51cefc638b1426b9,
+ 0x2c37011a362d1b00,0x8893a5be9289bfa4, 0x2c37011a362d1b00,0x8893a5be9289bfa4,
+ 0x2dca39def314e700,0x17f003e4c92edd3a, 0x2dca39def314e700,0x17f003e4c92edd3a,
+ 0x7bcfdd6912a6b400,0x9c283a8ef54153e7, 0x7bcfdd6912a6b400,0x9c283a8ef54153e7,
+ 0xbdff7e3c81c34200,0x6426a7e5581a9bd9, 0xbdff7e3c81c34200,0x6426a7e5581a9bd9,
+ 0x2d7e6a3914475300,0x1f4c580b26756132, 0x2d7e6a3914475300,0x1f4c580b26756132,
+ 0xe60dbb50b65deb00,0xc72c9a71977cca21, 0xe60dbb50b65deb00,0xc72c9a71977cca21,
+ 0xc88d03468ecb4500,0x286de3a66e2ba5e0, 0xc88d03468ecb4500,0x286de3a66e2ba5e0,
+ 0x60fad44e2eb49a00,0xfe644ad0b02a049e, 0x60fad44e2eb49a00,0xfe644ad0b02a049e,
+ 0xce83511cd29f4d00,0x400ddf925c11c38e, 0xce83511cd29f4d00,0x400ddf925c11c38e,
+ 0xb4b76665d1d20300,0x1310c1c27675a4a7, 0xb4b76665d1d20300,0x1310c1c27675a4a7,
+ 0x5031f293c3a26100,0x5233f091c1a06302, 0x5031f293c3a26100,0x5233f091c1a06302,
+ 0x96f69cfc6a0a6000,0x5d3d5737a1c1abcb, 0x96f69cfc6a0a6000,0x5d3d5737a1c1abcb,
+ 0x87cb105cdb974c00,0x155982ce4905de92, 0x87cb105cdb974c00,0x155982ce4905de92,
+ 0x8c41ea27ab66cd00,0x569b30fd71bc17da, 0x8c41ea27ab66cd00,0x569b30fd71bc17da,
+ 0x720bdda4d6af7900,0x30499fe694ed3b42, 0x720bdda4d6af7900,0x30499fe694ed3b42,
+ 0xf41093778367e400,0xa541c226d236b551, 0xf41093778367e400,0xa541c226d236b551,
+ 0xf3337cbc4f8fc000,0x12d29d5dae6e21e1, 0xf3337cbc4f8fc000,0x12d29d5dae6e21e1,
+ 0xf8fa8f8d75770200,0xd2d0a5a75f5d282a, 0xf8fa8f8d75770200,0xd2d0a5a75f5d282a,
+ 0x548315c29641d700,0x67b026f1a572e433, 0x548315c29641d700,0x67b026f1a572e433,
+ 0x62974abfdd28f500,0xd326fb0e6c9944b1, 0x62974abfdd28f500,0xd326fb0e6c9944b1,
+ 0x9b0a54c55ecf9100,0x2fbee071ea7b25b4, 0x9b0a54c55ecf9100,0x2fbee071ea7b25b4,
+ 0x55e5ad1d48f8b000,0x4cfcb40451e1a919, 0x55e5ad1d48f8b000,0x4cfcb40451e1a919,
+ 0xc127e90fce28e600,0x8d6ba5438264aa4c, 0xc127e90fce28e600,0x8d6ba5438264aa4c,
+ 0x47b146b6f107f00,0xeb94fb8480ff90ef, 0x47b146b6f107f00,0xeb94fb8480ff90ef,
+ 0x4e7b1326685d3500,0xe6d3bb8ec0f59da8, 0x4e7b1326685d3500,0xe6d3bb8ec0f59da8,
+ 0x7b750c0279770e00,0x737d040a717f0608, 0x7b750c0279770e00,0x737d040a717f0608,
+ 0x2e18380e20163600,0xcff9d9efc1f7d7e1, 0x2e18380e20163600,0xcff9d9efc1f7d7e1,
+ 0x4a592b3872611300,0x9784f6e5afbccedd, 0x4a592b3872611300,0x9784f6e5afbccedd,
+ 0x6344654221062700,0x6c4b6a4d2e09280f, 0x6344654221062700,0x6c4b6a4d2e09280f,
+ 0x74787874000c0c00,0xf7fbfbf7838f8f83, 0x74787874000c0c00,0xf7fbfbf7838f8f83,
+ 0xebdb8bbb50603000,0x51613101eada8aba, 0xebdb8bbb50603000,0x51613101eada8aba,
+ 0x73f75adead298400,0x8400ad295ade73f7, 0x73f75adead298400,0x8400ad295ade73f7,
+ 0xda3f769349ace500,0x9c7930d50feaa346, 0xda3f769349ace500,0x9c7930d50feaa346,
+ 0xb59c80a91c352900,0xe8c1ddf44168745d, 0xb59c80a91c352900,0xe8c1ddf44168745d,
+ 0xda328e66bc54e800,0x38d06c845eb60ae2, 0xda328e66bc54e800,0x38d06c845eb60ae2,
+ 0x30ab6ff4c45f9b00,0xda41851e2eb571ea, 0x30ab6ff4c45f9b00,0xda41851e2eb571ea,
+ 0x305a4b21117b6a00,0x600a1b71412b3a50, 0x305a4b21117b6a00,0x600a1b71412b3a50,
+ 0x2830190129311800,0x425a736b435b726a, 0x2830190129311800,0x425a736b435b726a,
+ 0x79cafa493083b300,0x843707b4cd7e4efd, 0x79cafa493083b300,0x843707b4cd7e4efd,
+ 0x586cb185dde93400,0xa7934e7a2216cbff, 0x586cb185dde93400,0xa7934e7a2216cbff,
+ 0x2b3e8792b9ac1500,0x9c8930250e1ba2b7, 0x2b3e8792b9ac1500,0x9c8930250e1ba2b7,
+ 0x702ffca3d38c5f00,0x4619ca95e5ba6936, 0x702ffca3d38c5f00,0x4619ca95e5ba6936,
+ 0xed9c7908e5947100,0x4736d3a24f3edbaa, 0xed9c7908e5947100,0x4736d3a24f3edbaa,
+ 0x3a34bbb58f810e00,0xbcb23d3309078886, 0x3a34bbb58f810e00,0xbcb23d3309078886,
+ 0x3b45f688b3cd7e00,0xf6883b457e00b3cd, 0x3b45f688b3cd7e00,0xf6883b457e00b3cd,
+ 0x1bd675b8a36ecd00,0xc30ead607bb615d8, 0x1bd675b8a36ecd00,0xc30ead607bb615d8,
+ 0xc1f4deeb2a1f3500,0xc1f4deeb2a1f3500, 0xc1f4deeb2a1f3500,0xc1f4deeb2a1f3500,
+ 0xda9594db014e4f00,0x1d52531cc68988c7, 0xda9594db014e4f00,0x1d52531cc68988c7,
+ 0x97aa89b4231e3d00,0x54694a77e0ddfec3, 0x97aa89b4231e3d00,0x54694a77e0ddfec3,
+ 0x80904c5cdccc1000,0xeafa2636b6a67a6a, 0x80904c5cdccc1000,0xeafa2636b6a67a6a,
+ 0x22c13eddff1ce300,0xcc2fd03311f20dee, 0x22c13eddff1ce300,0xcc2fd03311f20dee,
+ 0xe0435bf818bba300,0x63c0d87b9b382083, 0xe0435bf818bba300,0x63c0d87b9b382083,
+ 0x77d92e80f759ae00,0x8a651ff8826d17f, 0x77d92e80f759ae00,0x8a651ff8826d17f,
+ 0xa7f0184fe8bf5700,0x4215fdaa0d5ab2e5, 0xa7f0184fe8bf5700,0x4215fdaa0d5ab2e5,
+ 0x238ff65a79d5ac00,0x76daa30f2c80f955, 0x238ff65a79d5ac00,0x76daa30f2c80f955,
+ 0xa3943c0ba89f3700,0xba8d2512b1862e19, 0xa3943c0ba89f3700,0xba8d2512b1862e19,
+ 0x7992a54e37dceb00,0xea0136dda44f7893, 0x7992a54e37dceb00,0xea0136dda44f7893,
+ 0x205e2e50700e7e00,0x3d43334d6d13631d, 0x205e2e50700e7e00,0x3d43334d6d13631d,
+ 0xe0ce5a7494ba2e00,0x8ba5311fffd1456b, 0xe0ce5a7494ba2e00,0x8ba5311fffd1456b,
+ 0x2ece81614fafe000,0x1dfdb2527c9cd333, 0x2ece81614fafe000,0x1dfdb2527c9cd333,
+ 0xf3f7afab585c0400,0xc2c69e9a696d3531, 0xf3f7afab585c0400,0xc2c69e9a696d3531,
+ 0x4d73615f122c3e00,0x8fb1a39dd0eefcc2, 0x4d73615f122c3e00,0x8fb1a39dd0eefcc2,
+ 0x716acfd4a5be1b00,0x5348edf6879c3922, 0x716acfd4a5be1b00,0x5348edf6879c3922,
+ 0x487d3500487d3500,0xc0f5bd88c0f5bd88, 0x487d3500487d3500,0xc0f5bd88c0f5bd88,
+ 0xba39c447fd7e8300,0x2dae53d06ae91497, 0xba39c447fd7e8300,0x2dae53d06ae91497,
+ 0x3ee84197a97fd600,0xd701a87e40963fe9, 0x3ee84197a97fd600,0xd701a87e40963fe9,
+ 0x98fa482ab2d06200,0x553785e77f1dafcd, 0x98fa482ab2d06200,0x553785e77f1dafcd,
+ 0xd5ea93ac79463f00,0x81bec7f82d126b54, 0xd5ea93ac79463f00,0x81bec7f82d126b54,
+ 0x23dfb844679bfc00,0xcf0976b48b4d32f, 0x23dfb844679bfc00,0xcf0976b48b4d32f,
+ 0xecb6b0ea065c5a00,0x7923257f93c9cf95, 0xecb6b0ea065c5a00,0x7923257f93c9cf95,
+ 0xa0e6480eaee84600,0xe9af0147e7a10f49, 0xa0e6480eaee84600,0xe9af0147e7a10f49,
+ 0xa1a2191abbb80300,0xd5d66d6ecfcc7774, 0xa1a2191abbb80300,0xd5d66d6ecfcc7774,
+ 0x9672a444d236e00,0xd8b6fb959cf2bfd1, 0x9672a444d236e00,0xd8b6fb959cf2bfd1,
+ 0x20d8a25a7a82f800,0x3fb817959a1db23, 0x20d8a25a7a82f800,0x3fb817959a1db23,
+ 0x48f6803e76c8be00,0x2e90e65810aed866, 0x48f6803e76c8be00,0x2e90e65810aed866,
+ 0xffebd3c7382c1400,0x77635b4fb0a49c88, 0xffebd3c7382c1400,0x77635b4fb0a49c88,
+ 0xfce2d5cb37291e00,0x4957607e829cabb5, 0xfce2d5cb37291e00,0x4957607e829cabb5,
+ 0xa7ff93cb6c345800,0xa9f19dc5623a560e, 0xa7ff93cb6c345800,0xa9f19dc5623a560e,
+ 0xb7059c2e992bb200,0x74c65fed5ae871c3, 0xb7059c2e992bb200,0x74c65fed5ae871c3,
+ 0xa1095ef657ffa800,0x5adfa52f35b0ca4, 0xa1095ef657ffa800,0x5adfa52f35b0ca4,
+ 0x31d8a34a7b92e900,0xbd542fc6f71e658c, 0x31d8a34a7b92e900,0xbd542fc6f71e658c,
+ 0x97a6fdcc5b6a3100,0x29184372e5d48fbe, 0x97a6fdcc5b6a3100,0x29184372e5d48fbe,
+ 0x168869f7e17f9e00,0x801eff6177e90896, 0x168869f7e17f9e00,0x801eff6177e90896,
+ 0xbbdf7216adc96400,0xcaae0367dcb81571, 0xbbdf7216adc96400,0xcaae0367dcb81571,
+ 0xa50909a500acac00,0xff5353ff5af6f65a, 0xa50909a500acac00,0xff5353ff5af6f65a,
+ 0x5ce4ff471ba3b800,0x7bfa41c40f8e35b, 0x5ce4ff471ba3b800,0x7bfa41c40f8e35b,
+ 0x7531d494e1a5400,0x4d19570304501e4a, 0x7531d494e1a5400,0x4d19570304501e4a,
+ 0xd97ccf6ab316a500,0xeb4efd5881249732, 0xd97ccf6ab316a500,0xeb4efd5881249732,
+ 0x47f0f34403b4b700,0xbbcbf084ff8fb4c, 0x47f0f34403b4b700,0xbbcbf084ff8fb4c,
+ 0x7d77c7cdb0ba0a00,0x7379c9c3beb4040e, 0x7d77c7cdb0ba0a00,0x7379c9c3beb4040e,
+ 0xd4331bfc28cfe700,0x30d7ff18cc2b03e4, 0xd4331bfc28cfe700,0x30d7ff18cc2b03e4,
+ 0xf2546fc93b9da600,0xf3556ec83a9ca701, 0xf2546fc93b9da600,0xf3556ec83a9ca701,
+ 0xfc3cb2728e4ec000,0xea2aa4649858d616, 0xfc3cb2728e4ec000,0xea2aa4649858d616,
+ 0x1a8882100a989200,0x1f8d87150f9d9705, 0x1a8882100a989200,0x1f8d87150f9d9705,
+ 0xa2d41365c7b17600,0xb7dbacc6e18dfa9, 0xa2d41365c7b17600,0xb7dbacc6e18dfa9,
+ 0xa66929e6408fcf00,0xe32c6ca305ca8a45, 0xa66929e6408fcf00,0xe32c6ca305ca8a45,
+ 0x39a7a739009e9e00,0xbd2323bd841a1a84, 0x39a7a739009e9e00,0xbd2323bd841a1a84,
+ 0xd20f9f42904ddd00,0xb76afa27f528b865, 0xd20f9f42904ddd00,0xb76afa27f528b865,
+ 0xd02336c515e6f300,0x5ba8bd4e9e6d788b, 0xd02336c515e6f300,0x5ba8bd4e9e6d788b,
+ 0x6322632241004100,0x92d392d3b0f1b0f1, 0x6322632241004100,0x92d392d3b0f1b0f1,
+ 0xcd4035b875f88d00,0xea67129f52dfaa27, 0xcd4035b875f88d00,0xea67129f52dfaa27,
+ 0xf4f21a1ce8ee0600,0xadab4345b1b75f59, 0xf4f21a1ce8ee0600,0xadab4345b1b75f59,
+ 0x8d80010c818c0d00,0xb6bb3a37bab7363b, 0x8d80010c818c0d00,0xb6bb3a37bab7363b,
+ };
+
+
+}
diff --git a/btfy.c b/btfy.c
deleted file mode 100644
index fb9fd53..0000000
--- a/btfy.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#include
-
-#include "gfext_aesni.h"
-
-#include "byte_inline_func.h"
-
-#include "config_profile.h"
-
-#include "string.h"
-
-
-
-/////////////////////////////////////////////////
-///
-/// field isomorphism. Cantor --> GF(2^128).
-///
-//////////////////////////////////////////////////////
-
-
-#include "bitmat_prod.h"
-
-#include "gf2128_cantor_iso.h"
-
-static inline
-__m128i gf_isomorphism_single_bit( unsigned ith_bit )
-{
- return _mm_load_si128( (__m128i*) (&gfCantorto2128[ith_bit]) );
-}
-
-static inline
-__m128i gf_isomorphism( uint64_t a_in_cantor )
-{
- uint8_t a_iso[16] __attribute__((aligned(32)));
- bitmatrix_prod_64x128_8R_sse( a_iso , gfCantorto2128_8R , a_in_cantor );
- return _mm_load_si128( (__m128i*) a_iso );
-}
-
-
-
-/////////////////////////////////////////////////
-///
-/// Butterfly network. pclmulqdq version.
-///
-//////////////////////////////////////////////////////
-
-
-
-/////// one layer /////////////////////
-
-static inline
-__m128i butterfly( __m128i * poly , unsigned unit , unsigned ska , __m128i extra_a )
-{
- __m128i a = extra_a;
- a ^= gf_isomorphism( ska );
-
- unsigned unit_2= unit/2;
- for(unsigned i=0;i3 ; i--) {
- unsigned unit = (1<<(i-1));
- unsigned num = (n_terms>>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st = (offset>>1)/unit;
- for(unsigned j= st;j2 ; i--) {
- unsigned unit = (1<<(i-1));
- unsigned num = (n_terms>>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st = (offset>>1)/unit;
- for(unsigned j= st;j1 ; i--) {
- unsigned unit = (1<<(i-1));
- unsigned num = (n_terms>>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st = (offset>>1)/unit;
- for(unsigned j= st;j0 ) {
- unsigned unit = (1< k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st=offset/unit;
- for(unsigned j=st;j k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st=offset/unit;
- for(unsigned j=st;j>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st = (offset>>1)/unit;
- for(unsigned j=st;j>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st = (offset>>1)/unit;
- for(unsigned j=st;j>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- unsigned st = (offset>>1)/unit;
- for(unsigned j=st;j= n_fx ) return;
-
- unsigned log_n = __builtin_ctz( n_fx );
- unsigned n_terms = n_fx;
-
- unsigned i=log_n;
-
- __m256i * poly256 = (__m256i*) &fx[0];
- for( ; i> _LOG_CACHE_SIZE_ ; i--) {
- unsigned unit = (1<<(i-1));
- unsigned num = (n_terms>>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j= n_fx ) return;
-
- unsigned log_n = __builtin_ctz( n_fx );
-
- unsigned n_terms = n_fx;
-
- {
- unsigned unit = ((1<<_LOG_CACHE_SIZE_) > n_fx)? n_fx : (1<<_LOG_CACHE_SIZE_);
- unsigned num = n_terms/unit;
- for(unsigned j=0;j>1) / unit;
-
- unsigned k = i-1;
- __m128i extra_a = (scalar_a > k ) ? gf_isomorphism_single_bit( (scalar_a-k-1)<<1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>1
-{
- __m128i a = extra_a;
- a ^= gf264_isomorphism( ska );
- poly[0] = butterfly_64_xmm( poly[0] , a );
- _mm_prefetch( &poly[1] , _MM_HINT_T0 );
- return a;
-}
-
-static inline
-__m128i i_butterfly_64_u2( __m128i * poly , unsigned ska , __m128i extra_a ) /// unit = 2>>1
-{
- __m128i a = extra_a;
- a ^= gf264_isomorphism( ska );
- poly[0] = i_butterfly_64_xmm( poly[0] , a );
- _mm_prefetch( &poly[1] , _MM_HINT_T0 );
- return a;
-}
-
-////////////////////////////
-
-
-static inline
-__m256i butterfly_64_ymm( __m256i d , __m128i a )
-{
- __m128i d0 = _mm256_castsi256_si128( d );
- __m128i d1 = _mm256_extracti128_si256( d , 1 );
- d0 ^= _gf2ext64_mul_2x1_sse( d1 , a );
- d1 ^= d0;
- __m256i r0 = _mm256_castsi128_si256( d0 );
- __m256i r1 = _mm256_inserti128_si256( r0 , d1 , 1 );
- return r1;
-}
-
-static inline
-__m256i i_butterfly_64_ymm( __m256i d , __m128i a )
-{
- __m128i d0 = _mm256_castsi256_si128( d );
- __m128i d1 = _mm256_extracti128_si256( d , 1 );
- d1 ^= d0;
- d0 ^= _gf2ext64_mul_2x1_sse( d1 , a );
- __m256i r0 = _mm256_castsi128_si256( d0 );
- __m256i r1 = _mm256_inserti128_si256( r0 , d1 , 1 );
- return r1;
-}
-
-static inline
-__m128i butterfly_64_u4( __m256i * poly , unsigned ska , __m128i extra_a ) /// unit = 4>>2
-{
- __m128i a = extra_a;
- a ^= gf264_isomorphism( ska );
- poly[0] = butterfly_64_ymm( poly[0] , a );
- _mm_prefetch( &poly[1] , _MM_HINT_T0 );
- return a;
-}
-
-static inline
-__m128i i_butterfly_64_u4( __m256i * poly , unsigned ska , __m128i extra_a ) /// unit = 4>>2
-{
- __m128i a = extra_a;
- a ^= gf264_isomorphism( ska );
- poly[0] = i_butterfly_64_ymm( poly[0] , a );
- _mm_prefetch( &poly[1] , _MM_HINT_T0 );
- return a;
-}
-
-
-//////////////////////////////////////////////////
-
-
-static inline
-__m128i butterfly_64_avx2( __m256i * poly , unsigned unit , unsigned ska , __m128i extra_a ) /// unit >= 8>>2
-{
- __m128i a = extra_a;
- a ^= gf264_isomorphism( ska );
-
- unsigned unit_2= unit/2;
- for(unsigned i=0;i= n_fx ) return;
-
- unsigned log_n = __builtin_ctz( n_fx );
- unsigned n_terms = n_fx;
-
- unsigned i=log_n;
-
- uint64_t * poly = fx;
- for( ; i>4; i-- ) {
- unsigned unit = (1<= 8
- unsigned num = n_terms / unit;
-
- unsigned k = i-1;
- __m128i extra_a = ( scalar_a > k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>2 , diff_j<<1 , extra_a );
- }
- }
- for( ; i>3; i-- ) {
- unsigned unit = (1<= 8
- unsigned num = n_terms / unit;
-
- unsigned k = i-1;
- __m128i extra_a = ( scalar_a > k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>2 , diff_j<<1 , extra_a );
- }
- }
- for( ; i>2; i-- ) {
- unsigned unit = (1<= 8
- unsigned num = n_terms / unit;
-
- unsigned k = i-1;
- __m128i extra_a = ( scalar_a > k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>2 , diff_j<<1 , extra_a );
- }
- }
- for( ; i>1; i-- ) {
- unsigned unit = (1< k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j0; i-- ) {
- unsigned unit = (1< k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j= n_fx ) return;
-
- unsigned log_n = __builtin_ctz( n_fx );
- unsigned n_terms = n_fx;
-
- uint64_t * poly = fx;
- unsigned i=1;
- for( ; i<2; i++ ) {
- unsigned unit = (1< k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j= 8
- unsigned num = n_terms / unit;
-
- unsigned k = i-1;
- __m128i extra_a = ( scalar_a > k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>2 , diff_j<<1 , extra_a );
- }
- }
- for( ; i<5; i++ ) {
- unsigned unit = (1<= 8
- unsigned num = n_terms / unit;
-
- unsigned k = i-1;
- __m128i extra_a = ( scalar_a > k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>2 , diff_j<<1 , extra_a );
- }
- }
- for( ; i<=log_n; i++ ) {
- unsigned unit = (1<= 8
- unsigned num = n_terms / unit;
-
- unsigned k = i-1;
- __m128i extra_a = ( scalar_a > k )? gf264_isomorphism_single_bit( scalar_a - k - 1 ) : _mm_setzero_si128();
-
- unsigned last_j = 0;
- for(unsigned j=0;j>2 , diff_j<<1 , extra_a );
- }
- }
-}
diff --git a/btfy.h b/btfy.h
deleted file mode 100644
index 9cfe05b..0000000
--- a/btfy.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#ifndef _BTFY_H_
-#define _BTFY_H_
-
-
-#include
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-void btfy_128( uint64_t * fx , unsigned n_fx , unsigned scalar_a );
-
-void i_btfy_128( uint64_t * fx , unsigned n_fx , unsigned scalar_a );
-
-
-void btfy_64( uint64_t * fx , unsigned n_fx , unsigned scalar_a );
-
-void i_btfy_64( uint64_t * fx , unsigned n_fx , unsigned scalar_a );
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/build.py b/build.py
new file mode 100644
index 0000000..a41d989
--- /dev/null
+++ b/build.py
@@ -0,0 +1,152 @@
+import os
+import platform
+import sys
+import multiprocessing
+
+def getParallel(args):
+ par = multiprocessing.cpu_count()
+ for x in args:
+ if x.startswith("--par="):
+ val = x.split("=",1)[1]
+ par = int(val)
+ if par < 1:
+ par = 1
+ return par
+
+
+def Build(projectName, mainArgs, cmakeArgs,install, prefix, par):
+
+ osStr = (platform.system())
+ buildDir = ""
+ config = ""
+ buildType = ""
+ if "--Debug" in mainArgs or "--debug" in mainArgs:
+ buildType = "Debug"
+ else:
+ buildType = "Release"
+
+ if osStr == "Windows":
+ buildDir = "out/build/x64-{0}".format(buildType)
+ config = "--config {0}".format(buildType)
+ else:
+ buildDir = "out/build/linux"
+
+ cmakeArgs.append("-DCMAKE_BUILD_TYPE={0}".format(buildType))
+
+ argStr = ""
+ for a in cmakeArgs:
+ argStr = argStr + " " + a
+
+ parallel = ""
+ if par != 1:
+ parallel = " --parallel " + str(par)
+
+ mkDirCmd = "mkdir -p {0}".format(buildDir);
+ CMakeCmd = "cmake -S . -B {0} {1}".format(buildDir, argStr)
+ BuildCmd = "cmake --build {0} {1} {2} ".format(buildDir, config, parallel)
+
+
+ InstallCmd = ""
+ sudo = ""
+ if "--sudo" in sys.argv:
+ sudo = "sudo "
+
+ if install:
+ InstallCmd = sudo
+ InstallCmd += "cmake --install {0} {1} ".format(buildDir, config)
+
+ if len(prefix):
+ InstallCmd += " --prefix {0} ".format(prefix)
+
+ print("\n\n====== build.py ("+projectName+") ========")
+ print(mkDirCmd)
+ print(CMakeCmd)
+ print(BuildCmd)
+ if len(InstallCmd):
+ print(InstallCmd)
+ print("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\n")
+
+ os.system(mkDirCmd)
+ os.system(CMakeCmd)
+ os.system(BuildCmd)
+
+ if len(sudo) > 0:
+ print("installing "+projectName+": {0}".format(InstallCmd))
+
+ os.system(InstallCmd)
+
+
+def getInstallArgs(args):
+ prefix = ""
+ for x in args:
+ if x.startswith("--install="):
+ prefix = x.split("=",1)[1]
+ prefix = os.path.abspath(os.path.expanduser(prefix))
+ return (True, prefix)
+ if x == "--install":
+ return (True, "")
+ return (False, "")
+
+
+def parseArgs():
+ hasCmakeArgs = "--" in sys.argv
+ mainArgs = []
+ cmakeArgs = []
+
+ if hasCmakeArgs:
+ idx = sys.argv.index("--")
+ mainArgs = sys.argv[:idx]
+ cmakeArgs = sys.argv[idx+1:]
+
+ else:
+ mainArgs = sys.argv
+
+
+ return (mainArgs, cmakeArgs)
+
+def help():
+ print(" --setup \n\tfetch, build and optionally install the dependencies. \
+ Must also pass --relic, --sodium and/or --boost to specify which to build. Without \
+ --setup, the main library is built.")
+
+ print(" --install \n\tInstructs the script to install whatever is currently being built to the default location.")
+ print(" --install=prefix \n\tinstall to the provided predix.")
+ print(" --sudo \n\twhen installing, use sudo. May require password.")
+ print(" --par=n \n\twhen building do use parallel builds with n threads. default = num cores.")
+ print(" -- \n\tafter the \"--\" argument, all command line args are passed to cmake")
+
+ print("\n\nExamples:")
+ print("-fetch the dependancies and dont install")
+ print(" python build.py --setup --boost --relic")
+ print("-fetch the dependancies and install with sudo")
+ print(" python build.py --setup --boost --relic --install --sudo")
+ print("-fetch the dependancies and install to a specified location")
+ print(" python build.py --setup --boost --relic --install=~/my/install/dir")
+ print("")
+ print("-build the main library")
+ print(" python build.py")
+ print("-build the main library with cmake configurations")
+ print(" python build.py -- -DCMAKE_BUILD_TYPE=Debug -DENABLE_SSE=ON")
+ print("-build the main library and install with sudo")
+ print(" python build.py --install --sudo")
+ print("-build the main library and install to prefix")
+ print(" python build.py --install=~/my/install/dir ")
+
+
+
+
+def main(projectName):
+
+ (mainArgs, cmake) = parseArgs()
+ if "--help" in mainArgs:
+ help()
+ return
+
+ install, prefix = getInstallArgs(mainArgs)
+ par = getParallel(mainArgs)
+
+ Build(projectName, mainArgs, cmake,install, prefix, par)
+
+if __name__ == "__main__":
+
+ main("bitpolymul")
diff --git a/butterfly_net.c b/butterfly_net.c
deleted file mode 100644
index c5b6909..0000000
--- a/butterfly_net.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#include
-
-#include "gfext_aesni.h"
-
-#include "bitmat_prod.h"
-
-#include "byte_inline_func.h"
-
-#include "config_profile.h"
-
-#include "string.h"
-
-
-/////////////////////////////////////////////////
-///
-/// pclmulqdq version
-///
-//////////////////////////////////////////////////////
-
-#include "gf2128_cantor_iso.h"
-
-#include "ska.h"
-
-static
-void butterfly_0( __m128i * poly , unsigned unit )
-{
- unsigned unit_2= unit/2;
- for(unsigned i=0;i= n_fx ) return;
-
- unsigned log_n = __builtin_ctz( n_fx );
-
- unsigned n_terms = n_fx;
-
- __m128i * poly = (__m128i*) &fx[0];
-
- /// first layer
- memcpy( poly + (n_terms/2) , poly , 8*n_terms );
-
- for(unsigned i=log_n-1; i>0 ; i--) {
- unsigned unit = (1<= n_fx ) return;
-
- unsigned log_n = __builtin_ctz( n_fx );
-
- __m128i *poly = (__m128i*) &fx[0];
- unsigned n_terms = n_fx;
-
- for(unsigned i=1; i <= log_n; i++) {
- unsigned unit = (1<.
-*/
-
-#ifndef _BYTE_INLINE_FUNC_H_
-#define _BYTE_INLINE_FUNC_H_
-
-#include
-#include
-#include
-
-
-
-static inline
-unsigned byte_is_zero( const uint64_t * vec , unsigned n ) { unsigned r=0; for(unsigned i=0;i
-
-static inline
-void xmm_rand( __m128i * vec , unsigned n ) { byte_rand((uint8_t*)vec,n*16); }
-
-static inline
-uint64_t xmm_is_zero( const __m128i * vec , unsigned n ) {
- __m128i r=_mm_setzero_si128();
- for(unsigned i=0;i.
-*/
-
-
-#include
-
-#include "gfext_aesni.h"
-
-#include "bitmat_prod.h"
-
-#include "byte_inline_func.h"
-
-#include "config_profile.h"
-
-#include "string.h"
-
-
-
-
-
-/////////////////////////////////////////////////
-///
-/// truncated FFT, 7 layers
-///
-//////////////////////////////////////////////////////
-
-#include "trunc_btfy_tab.h"
-
-#include "transpose.h"
-
-
-
-static inline
-void bit_bc_64x2_div( __m256i * x )
-{
- for(unsigned i=0;i<64;i++) x[64+i] = _mm256_srli_si256( x[i] , 8 );
- for(int i=64-1;i>=0;i--) {
- x[1+i] ^= x[64+i];
- x[4+i] ^= x[64+i];
- x[16+i] ^= x[64+i];
- }
- for(unsigned i=0;i<64;i++) x[i] = _mm256_unpacklo_epi64( x[i] , x[64+i] );
-
- for(unsigned i=0;i<64;i+=64) {
- __m256i * pi = x + i;
- for(int j=32-1;j>=0;j--) {
- pi[1+j] ^= pi[32+j];
- pi[2+j] ^= pi[32+j];
- pi[16+j] ^= pi[32+j];
- }
- }
- for(unsigned i=0;i<64;i+=32) {
- __m256i * pi = x + i;
- for(int j=16-1;j>=0;j--) {
- pi[1+j] ^= pi[16+j];
- }
- }
- for(unsigned i=0;i<64;i+=16) {
- __m256i * pi = x + i;
- for(int j=8-1;j>=0;j--) {
- pi[1+j] ^= pi[8+j];
- pi[2+j] ^= pi[8+j];
- pi[4+j] ^= pi[8+j];
- }
- }
- for(unsigned i=0;i<64;i+=8) {
- __m256i * pi = x + i;
- pi[4] ^= pi[7];
- pi[3] ^= pi[6];
- pi[2] ^= pi[5];
- pi[1] ^= pi[4];
- }
-
- for(unsigned i=0;i<64;i+=4) {
- __m256i * pi = x + i;
- pi[2] ^= pi[3];
- pi[1] ^= pi[2];
- }
-
-}
-
-
-
-void encode_128_half_input_zero( uint64_t * rfx , const uint64_t * fx , unsigned n_fx_128b )
-{
- if(128*2 > n_fx_128b) { printf("unsupported number of terms.\n"); exit(-1); }
-
- __m256i temp[128];
- __m128i * temp128 = (__m128i*) temp;
- uint64_t * temp64 = (uint64_t *)temp;
- const __m256i * fx_256 = (const __m256i*) fx;
- __m128i * rfx_128 = (__m128i*) rfx;
- unsigned n_fx_256b = n_fx_128b/2;
- unsigned num = n_fx_256b/128;
- __m256i t2[128];
- __m128i * t2_128 = (__m128i*) t2;
-
- for(unsigned i=0;i < num; i ++ ){
- for(unsigned j=0;j<64;j++) {
- temp[j] = fx_256[i + j*num];
- temp[j] = div_s7( temp[j] );
- }
-
- tr_bit_64x64_b4_avx2( (uint8_t*)(temp128) , (const uint8_t *)temp );
- bit_bc_64x2_div( temp );
- // truncated FFT
- for(unsigned j=0;j<8;j++) {
- bitmatrix_prod_64x128_4R_b32_opt_avx2( (uint8_t*)(&t2_128[32*j]) , beta_mul_64_bm4r_ext_8 , (const uint8_t *)(&temp64[32*j]) );
- }
- for(unsigned k=0;k<8;k++) for(unsigned j=0;j<8;j++) rfx_128[i*256+k*8+j] = t2_128[k*32+j*2];
- for(unsigned k=0;k<8;k++) for(unsigned j=0;j<8;j++) rfx_128[i*256+64+k*8+j] = t2_128[k*32+16+j*2];
- for(unsigned k=0;k<8;k++) for(unsigned j=0;j<8;j++) rfx_128[i*256+128+k*8+j] = t2_128[k*32+j*2+1];
- for(unsigned k=0;k<8;k++) for(unsigned j=0;j<8;j++) rfx_128[i*256+128+64+k*8+j] = t2_128[k*32+16+j*2+1];
- }
-}
-
-#if 1
-static inline
-void bit_bc_div( __m256i * x )
-{
- /// div s6 = x^64 + x^16 + x^4 + x
- for(int i=64-1;i>=0;i--) {
- x[1+i] ^= x[64+i];
- x[4+i] ^= x[64+i];
- x[16+i] ^= x[64+i];
- }
- /// div s5 = s^32 + x^16 + x^2 + x
- for(unsigned i=0;i<128;i+=64) {
- __m256i * pi = x + i;
- for(int j=32-1;j>=0;j--) {
- pi[1+j] ^= pi[32+j];
- pi[2+j] ^= pi[32+j];
- pi[16+j] ^= pi[32+j];
- }
- }
- /// div s4 = x^16 + x
- for(unsigned i=0;i<128;i+=32) {
- __m256i * pi = x + i;
- for(int j=16-1;j>=0;j--) {
- pi[1+j] ^= pi[16+j];
- }
- }
- /// div s3 = x^8 + x^4 + x^2 + x
- for(unsigned i=0;i<128;i+=16) {
- __m256i * pi = x + i;
- for(int j=8-1;j>=0;j--) {
- pi[1+j] ^= pi[8+j];
- pi[2+j] ^= pi[8+j];
- pi[4+j] ^= pi[8+j];
- }
- }
- /// div s2 = x^4 + x
- for(unsigned i=0;i<128;i+=8) {
- __m256i * pi = x + i;
- pi[4] ^= pi[7];
- pi[3] ^= pi[6];
- pi[2] ^= pi[5];
- pi[1] ^= pi[4];
- }
- /// div s1 = x^2 + x
- for(unsigned i=0;i<128;i+=4) {
- __m256i * pi = x + i;
- pi[2] ^= pi[3];
- pi[1] ^= pi[2];
- }
-}
-#else
-static inline
-void bit_bc_div( __m256i * x )
-{
- /// var substitue s4^4 = x^64 + x^4
- for(int i=64;i--;) x[4+i] ^= x[64+i];
- /// var substitue s4^2 = x32 + x^2
- for(int i=32;i--;) x[2+i] ^= x[32+i];
- /// var substitue s4 = x16 + x
- for(int i=16;i--;) x[1+i] ^= x[16+i];
- for(int i=16;i--;) x[1+32+i] ^= x[16+32+i];
-
- for(int i=32;i--;) x[2+64+i] ^= x[32+64+i];
- /// var substitue s4 = x16 + x
- for(int i=16;i--;) x[1+64+i] ^= x[16+64+i];
- for(int i=16;i--;) x[1+96+i] ^= x[16+96+i];
-
- /// 8 blocks, 16 elements per block
- for(unsigned i=0;i<16;i++) {
- /// div s6 = x^64 + x^16 + x^4 + x = s4^4 + s4
- x[4*16+i] ^= x[7*16+i];
- x[3*16+i] ^= x[6*16+i];
- x[2*16+i] ^= x[5*16+i];
- x[1*16+i] ^= x[4*16+i];
- /// div s5 = x^32 + x^16 + x^2 + x = s4^2 + s4
- x[6*16+i] ^= x[7*16+i];
- x[2*16+i] ^= x[3*16+i];
- x[5*16+i] ^= x[6*16+i];
- x[1*16+i] ^= x[2*16+i];
- }
- for(unsigned k=0;k<16;k++) {
- __m256i * f = &x[k*16];
- f[9] ^= f[15];
- f[8] ^= f[14];
- f[7] ^= f[13];
- f[6] ^= f[12];
- f[5] ^= f[11];
- f[4] ^= f[10];
- f[3] ^= f[9];
- f[2] ^= f[8];
-
- f[12] ^= f[15];
- f[11] ^= f[14];
- f[4] ^= f[7];
- f[3] ^= f[6];
-
- f[10] ^= f[13];
- f[9] ^= f[12];
- f[2] ^= f[5];
- f[1] ^= f[4];
-
- f[11] ^= f[15];
- f[10] ^= f[14];
- f[9] ^= f[13];
- f[8] ^= f[12];
- f[7] ^= f[11];
- f[6] ^= f[10];
- f[5] ^= f[9];
- f[4] ^= f[8];
-
- f[14] ^= f[15];
- f[10] ^= f[11];
- f[6] ^= f[7];
- f[2] ^= f[3];
-
- f[13] ^= f[14];
- f[9] ^= f[10];
- f[5] ^= f[6];
- f[1] ^= f[2];
- }
-}
-#endif
-
-void encode_128( uint64_t * rfx , const uint64_t * fx , unsigned n_fx_128b )
-{
- if(128*2 > n_fx_128b) { printf("unsupported number of terms.\n"); exit(-1); }
-
- __m256i temp[128];
- __m128i * temp128 = (__m128i*) temp;
- const __m256i * fx_256 = (const __m256i*) fx;
- __m128i * rfx_128 = (__m128i*) rfx;
- unsigned n_fx_256b = n_fx_128b/2;
- unsigned num = n_fx_256b/128;
-
- for(unsigned i=0;i < num; i ++ ){
- for(unsigned j=0;j<128;j++) {
- temp[j] = fx_256[i + j*num];
- temp[j] = div_s7( temp[j] );
- }
-
- tr_bit_128x128_b2_avx2( (uint8_t*)(temp128) , (const uint8_t *)temp );
- bit_bc_div( temp );
- // truncated FFT
- for(unsigned j=0;j<8;j++) {
- bitmatrix_prod_128x128_4R_b32_opt_avx2( (uint8_t*)(temp+16*j) , beta_mul_64_bm4r_ext_8 , (const uint8_t *)(temp+16*j) );
- }
- for(unsigned j=0;j<128;j++) rfx_128[i*256+j] = temp128[j*2];
- for(unsigned j=0;j<128;j++) rfx_128[i*256+128+j] = temp128[j*2+1];
- }
-}
-
-
-
-static inline
-void bit_bc_exp( __m256i * x )
-{
- for(unsigned i=0;i<128;i+=4) {
- __m256i * pi = x + i;
- pi[1] ^= pi[2];
- pi[2] ^= pi[3];
- }
- for(unsigned i=0;i<128;i+=8) {
- __m256i * pi = x + i;
- pi[1] ^= pi[4];
- pi[2] ^= pi[5];
- pi[3] ^= pi[6];
- pi[4] ^= pi[7];
- }
- for(unsigned i=0;i<128;i+=16) {
- __m256i * pi = x + i;
- for(unsigned j=0;j<8;j++) {
- pi[1+j] ^= pi[8+j];
- pi[2+j] ^= pi[8+j];
- pi[4+j] ^= pi[8+j];
- }
- }
- for(unsigned i=0;i<128;i+=32) {
- __m256i * pi = x + i;
- for(unsigned j=0;j<16;j++) {
- pi[1+j] ^= pi[16+j];
- }
- }
- for(unsigned i=0;i<128;i+=64) {
- __m256i * pi = x + i;
- for(unsigned j=0;j<32;j++) {
- pi[1+j] ^= pi[32+j];
- pi[2+j] ^= pi[32+j];
- pi[16+j] ^= pi[32+j];
- }
- }
- for(unsigned i=0;i<64;i++) {
- x[1+i] ^= x[64+i];
- x[4+i] ^= x[64+i];
- x[16+i] ^= x[64+i];
- }
-}
-
-
-void decode_128( uint64_t * rfx , const uint64_t * fx , unsigned n_fx_128b )
-{
- if(128*2 > n_fx_128b) { printf("unsupported number of terms.\n"); exit(-1); }
-
- const __m128i * fx_128 = (__m128i*) fx;
- __m256i * rfx_256 = (__m256i*) rfx;
- unsigned n_fx_256b = n_fx_128b/2;
- unsigned num = n_fx_256b/128;
- __m256i temp[128];
- __m128i * temp128 = (__m128i*) temp;
-
- for(unsigned i=0;i < num; i ++ ){
- /// truncated iFFT here.
- for(unsigned j=0;j<128;j++) {
- temp128[j*2] = fx_128[i*256+j];
- temp128[j*2+1] = fx_128[i*256+128+j];
- }
-
- for(unsigned j=0;j<8;j++) {
- bitmatrix_prod_128x128_4R_b32_opt_avx2( (uint8_t*)(temp+16*j) , i_beta_mul_64_bm4r_ext_8 , (const uint8_t *)(temp+16*j) );
- }
-
- bit_bc_exp( temp );
-
- tr_bit_128x128_b2_avx2( (uint8_t*)temp , (const uint8_t *)temp128 );
-
- for(unsigned j=0;j<128;j++) {
- temp[j] = exp_s7( temp[j] );
- rfx_256[i+j*num] = temp[j];
- }
- }
-}
-
-
-
-///////////////////////////////////////
-
-
-
-
-static inline
-void bit_bc_64x2_exp( __m256i * x )
-{
- for(unsigned i=0;i<64;i+=4) {
- __m256i * pi = x + i;
- pi[1] ^= pi[2];
- pi[2] ^= pi[3];
- }
- for(unsigned i=0;i<64;i+=8) {
- __m256i * pi = x + i;
- pi[1] ^= pi[4];
- pi[2] ^= pi[5];
- pi[3] ^= pi[6];
- pi[4] ^= pi[7];
- }
- for(unsigned i=0;i<64;i+=16) {
- __m256i * pi = x + i;
- for(unsigned j=0;j<8;j++) {
- pi[1+j] ^= pi[8+j];
- pi[2+j] ^= pi[8+j];
- pi[4+j] ^= pi[8+j];
- }
- }
- for(unsigned i=0;i<64;i+=32) {
- __m256i * pi = x + i;
- for(unsigned j=0;j<16;j++) {
- pi[1+j] ^= pi[16+j];
- }
- }
- for(unsigned i=0;i<64;i+=64) {
- __m256i * pi = x + i;
- for(unsigned j=0;j<32;j++) {
- pi[1+j] ^= pi[32+j];
- pi[2+j] ^= pi[32+j];
- pi[16+j] ^= pi[32+j];
- }
- }
-
- for(unsigned i=0;i<64;i++) x[64+i] = _mm256_srli_si256( x[i] , 8 );
- for(unsigned i=0;i<64;i++) {
- x[1+i] ^= x[64+i];
- x[4+i] ^= x[64+i];
- x[16+i] ^= x[64+i];
- }
- for(unsigned i=0;i<64;i++) x[i] = _mm256_unpacklo_epi64( x[i] , x[64+i] );
-
-}
-
-
-
-
-#include "trunc_btfy_tab_64.h"
-
-
-void encode_64_half_input_zero( uint64_t * rfx , const uint64_t * fx , unsigned n_fx ) /// XXX: further optimization.
-{
- if(64*4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); }
-
- __m256i temp[128];
- uint64_t * temp64 = (uint64_t *) temp;
- const __m256i * fx_256 = (const __m256i*) fx;
- unsigned n_fx_256b = n_fx>>2;
- unsigned num = n_fx_256b/64;
-
- for(unsigned i=0;i < num; i ++ ){
- for(unsigned j=0;j<32;j++) {
- temp[j] = fx_256[i + j*num];
- temp[j] = div_s7( temp[j] );
- }
- for(unsigned j=32;j<64;j++) temp[j] = _mm256_setzero_si256();
-
- tr_bit_64x64_b4_avx2( (uint8_t*)(temp) , (const uint8_t *)temp );
-
- bit_bc_64x2_div( temp );
-
- // truncated FFT
- //for(unsigned j=0;j<256;j++) temp64[j] = bitmatrix_prod_64x64_M4R( beta_mul_32_m4r , temp64[j] );
-#if 0
- for(unsigned j=0;j<(64*4/32);j++) bitmatrix_prod_64x64_h32zero_4R_b32_avx2( (uint8_t*)(&temp64[32*j]) , beta_mul_32_bm4r , (uint8_t*)(&temp64[32*j]) );
-#else
- for(unsigned j=0;j<(64*4/64);j++) bitmatrix_prod_64x64_h32zero_4R_b64_avx2( (uint8_t*)(&temp64[64*j]) , beta_mul_32_bm4r , (uint8_t*)(&temp64[64*j]) );
-#endif
-
- for(unsigned j=0;j<64;j++) rfx[i*256+j] = temp64[j*4] ;
- for(unsigned j=0;j<64;j++) rfx[i*256+64+j] = temp64[j*4+1] ;
- for(unsigned j=0;j<64;j++) rfx[i*256+128+j] = temp64[j*4+2] ;
- for(unsigned j=0;j<64;j++) rfx[i*256+192+j] = temp64[j*4+3] ;
-
- }
-}
-
-
-
-
-void encode_64( uint64_t * rfx , const uint64_t * fx , unsigned n_fx )
-{
- if(64*4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); }
-
- __m256i temp[128];
- uint64_t * temp64 = (uint64_t *) temp;
- const __m256i * fx_256 = (const __m256i*) fx;
- unsigned n_fx_256b = n_fx>>2;
- unsigned num = n_fx_256b/64;
-
- for(unsigned i=0;i < num; i ++ ){
- for(unsigned j=0;j<64;j++) {
- temp[j] = fx_256[i + j*num];
- temp[j] = div_s7( temp[j] );
- }
-
- tr_bit_64x64_b4_avx2( (uint8_t*)(temp) , (const uint8_t *)temp );
-
- bit_bc_64x2_div( temp );
-
- // truncated FFT
- //for(unsigned j=0;j<256;j++) temp64[j] = bitmatrix_prod_64x64_M4R( beta_mul_32_m4r , temp64[j] );
- for(unsigned j=0;j<(64*4/32);j++) bitmatrix_prod_64x64_4R_b32_avx2( (uint8_t*)(&temp64[32*j]) , beta_mul_32_bm4r , (uint8_t*)(&temp64[32*j]) );
- for(unsigned j=0;j<64;j++) rfx[i*256+j] = temp64[j*4] ;
- for(unsigned j=0;j<64;j++) rfx[i*256+64+j] = temp64[j*4+1] ;
- for(unsigned j=0;j<64;j++) rfx[i*256+128+j] = temp64[j*4+2] ;
- for(unsigned j=0;j<64;j++) rfx[i*256+192+j] = temp64[j*4+3] ;
- }
-}
-
-
-
-void decode_64( uint64_t * rfx , const uint64_t * fx , unsigned n_fx )
-{
- if(64*4 > n_fx) { printf("unsupported number of terms.\n"); exit(-1); }
-
- __m256i temp[128];
- uint64_t * temp64 = (uint64_t *) temp;
-
- __m256i * rfx_256 = (__m256i*) rfx;
- unsigned n_fx_256b = n_fx>>2;
- unsigned num = n_fx_256b/64;
-
- for(unsigned i=0;i < num; i ++ ){
- /// truncated iFFT here.
- for(unsigned j=0;j<64;j++) {
- temp64[j*4] = fx[i*256+j];
- temp64[j*4+1] = fx[i*256+64+j];
- temp64[j*4+2] = fx[i*256+128+j];
- temp64[j*4+3] = fx[i*256+192+j];
- }
- // truncated iFFT
- //for(unsigned j=0;j<64*4;j++) temp64[j] = bitmatrix_prod_64x64_M4R( i_beta_mul_32_m4r , temp64[j] );
-#if 0
- for(unsigned j=0;j<(64*4/32);j++) bitmatrix_prod_64x64_4R_b32_avx2( (uint8_t*)(&temp64[32*j]) , i_beta_mul_32_bm4r , (uint8_t*)(&temp64[32*j]) );
-#else
- for(unsigned j=0;j<(64*4/64);j++) bitmatrix_prod_64x64_4R_b64_avx2( (uint8_t*)(&temp64[64*j]) , i_beta_mul_32_bm4r , (uint8_t*)(&temp64[64*j]) );
-#endif
- bit_bc_64x2_exp( temp );
-
- tr_bit_64x64_b4_avx2( (uint8_t*)(temp) , (const uint8_t *)temp );
-
- for(unsigned j=0;j<64;j++) {
- temp[j] = exp_s7( temp[j] );
-#if 0
- _mm256_stream_si256 ( &rfx_256[i+j*num], temp[j] );
-#elif 1
- _mm256_store_si256 ( &rfx_256[i+j*num], temp[j] );
-#else
- rfx_256[i+j*num] = temp[j];
-#endif
- }
- }
-}
-
-
diff --git a/encode.h b/encode.h
deleted file mode 100644
index e2a9caa..0000000
--- a/encode.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#ifndef _ENCODE_H_
-#define _ENCODE_H_
-
-
-#include
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-
-void encode_128_half_input_zero( uint64_t * rfx , const uint64_t * fx , unsigned n_fx_128b );
-
-void encode_128( uint64_t * rfx , const uint64_t * fx , unsigned n_fx_128b );
-
-void decode_128( uint64_t * rfx , const uint64_t * fx , unsigned n_fx_128b );
-
-
-
-void encode_64_half_input_zero( uint64_t * rfx , const uint64_t * fx , unsigned n_fx );
-
-void encode_64( uint64_t * rfx , const uint64_t * fx , unsigned n_fx );
-
-void decode_64( uint64_t * rfx , const uint64_t * fx , unsigned n_fx );
-
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/gfext_aesni.h b/gfext_aesni.h
deleted file mode 100644
index ae191fd..0000000
--- a/gfext_aesni.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#ifndef _GF_EXT_AESNI_H_
-#define _GF_EXT_AESNI_H_
-
-
-#include
-
-//#include
-//#include
-#include
-
-
-/// X^64 + X^4 + X^3 + X + 1
-/// 0x1b
-static const uint64_t _gf2ext64_reducer[4] __attribute__((aligned(32))) = {0x415A776C2D361B00ULL,0x1bULL,0x415A776C2D361B00ULL,0x1bULL};
-
-static inline
-__m128i _gf2ext64_reduce_sse( __m128i x0 )
-{
- __m128i reducer = _mm_load_si128( (__m128i const*)_gf2ext64_reducer );
- //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
- __m128i r0 = _mm_clmulepi64_si128( x0 , reducer , 0x11 );
- __m128i r1 = _mm_shuffle_epi8( reducer , r0 );
- __m128i r2 = x0 ^ r0;
- r1 ^= _mm_slli_si128( r2 , 8 );
- return _mm_srli_si128( r1 , 8 );
-}
-
-
-static inline
-__m128i _gf2ext64_reduce_x2_sse( __m128i x0 , __m128i y0 )
-{
- __m128i reducer = _mm_load_si128( (__m128i const*)_gf2ext64_reducer );
- //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
- __m128i r0 = _mm_clmulepi64_si128( x0 , reducer , 0x11 );
- __m128i s0 = _mm_clmulepi64_si128( y0 , reducer , 0x11 );
- __m128i r2 = x0 ^ r0;
- __m128i s2 = y0 ^ s0;
- __m128i pr = _mm_unpacklo_epi64( r2 , s2 );
-
- __m128i rr = _mm_unpackhi_epi64( r0 , s0 );
- __m128i rr2 = _mm_shuffle_epi8( reducer , rr );
-
- return pr^rr2;
-}
-
-static inline
-__m256i _gf2ext64_reduce_x4_avx2( __m128i w0 , __m128i x0 , __m128i y0 , __m128i z0 )
-{
- __m256i reducer2 = _mm256_load_si256( (__m256i const*)_gf2ext64_reducer );
- //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
- __m128i reducer = _mm256_castsi256_si128( reducer2 );
- __m128i r0 = _mm_clmulepi64_si128( w0 , reducer , 0x11 );
- __m128i s0 = _mm_clmulepi64_si128( x0 , reducer , 0x11 );
- __m128i t0 = _mm_clmulepi64_si128( y0 , reducer , 0x11 );
- __m128i u0 = _mm_clmulepi64_si128( z0 , reducer , 0x11 );
- __m128i r2 = w0 ^ r0;
- __m128i s2 = x0 ^ s0;
- __m128i t2 = y0 ^ t0;
- __m128i u2 = z0 ^ u0;
- __m256i pr1 = _mm256_castsi128_si256( _mm_unpacklo_epi64( r2 , s2 ) );
- __m256i pr2 = _mm256_inserti128_si256( pr1 , _mm_unpacklo_epi64( t2 , u2 ) , 1 );
-
- __m256i rr1 = _mm256_castsi128_si256( _mm_unpackhi_epi64( r0 , s0 ) );
- __m256i rr2 = _mm256_inserti128_si256( rr1 , _mm_unpackhi_epi64( t0 , u0 ) , 1 );
- return pr2 ^ _mm256_shuffle_epi8( reducer2 , rr2 );
-}
-
-
-
-static inline
-__m128i _gf2ext64_mul_sse( __m128i a0 , __m128i b0 )
-{
- __m128i c0 = _mm_clmulepi64_si128( a0 , b0 , 0 );
- __m128i c3 = _gf2ext64_reduce_sse( c0 );
- return c3;
-}
-
-static inline
-__m128i _gf2ext64_mul_hi_sse( __m128i a0 , __m128i b0 )
-{
- __m128i c0 = _mm_clmulepi64_si128( a0 , b0 , 1 );
- __m128i c3 = _gf2ext64_reduce_sse( c0 );
- return c3;
-}
-
-static inline
-__m128i _gf2ext64_mul_2x1_sse( __m128i a0a1 , __m128i b0 )
-{
- __m128i c0 = _mm_clmulepi64_si128( a0a1 , b0 , 0 );
- __m128i c1 = _mm_clmulepi64_si128( a0a1 , b0 , 1 );
- __m128i c3 = _gf2ext64_reduce_x2_sse( c0 , c1 );
- return c3;
-}
-
-static inline
-__m256i _gf2ext64_mul_4x1_avx2( __m256i a , __m128i b0 )
-{
- __m128i al = _mm256_castsi256_si128( a );
- __m128i c0 = _mm_clmulepi64_si128( al , b0 , 0 );
- __m128i c1 = _mm_clmulepi64_si128( al , b0 , 1 );
- __m128i ah = _mm256_extracti128_si256( a , 1 );
- __m128i c2 = _mm_clmulepi64_si128( ah , b0 , 0 );
- __m128i c3 = _mm_clmulepi64_si128( ah , b0 , 1 );
-
- return _gf2ext64_reduce_x4_avx2( c0 , c1 , c2 , c3 );
-}
-
-static inline
-__m128i _gf2ext64_mul_2x2_sse( __m128i a0a1 , __m128i b0b1 )
-{
- __m128i c0 = _mm_clmulepi64_si128( a0a1 , b0b1 , 0 );
- __m128i c1 = _mm_clmulepi64_si128( a0a1 , b0b1 , 0x11 );
- __m128i c3 = _gf2ext64_reduce_x2_sse( c0 , c1 );
- return c3;
-}
-
-static inline
-__m256i _gf2ext64_mul_4x4_avx2( __m256i a , __m256i b )
-{
- __m128i al = _mm256_castsi256_si128( a );
- __m128i bl = _mm256_castsi256_si128( b );
- __m128i c0 = _mm_clmulepi64_si128( al , bl , 0 );
- __m128i c1 = _mm_clmulepi64_si128( al , bl , 0x11 );
- __m128i ah = _mm256_extracti128_si256( a , 1 );
- __m128i bh = _mm256_extracti128_si256( b , 1 );
- __m128i c2 = _mm_clmulepi64_si128( ah , bh , 0 );
- __m128i c3 = _mm_clmulepi64_si128( ah , bh , 0x11 );
-
- return _gf2ext64_reduce_x4_avx2( c0 , c1 , c2 , c3 );
-}
-
-
-
-static inline
-uint64_t gf2ext64_mul_u64( uint64_t a , uint64_t b )
-{
- uint64_t tmp[4] __attribute__((aligned(32)));
- tmp[0] = a;
- tmp[1] = 0;
- __m128i a0 = _mm_load_si128( (__m128i const *)tmp );
- tmp[0] = b;
- __m128i b0 = _mm_load_si128( (__m128i const *)tmp );
- __m128i c0 = _gf2ext64_mul_sse( a0 , b0 );
-
- _mm_store_si128((__m128i*) tmp , c0 );
- return tmp[0];
-}
-
-
-
-static inline
-void gf2ext64_mul_sse( uint8_t * c , const uint8_t * a , const uint8_t * b )
-{
- uint64_t tmp[4] __attribute__((aligned(32)));
- for(unsigned i=0;i<8;i++) ((uint8_t*)tmp)[i] = a[i];
- tmp[1] = 0;
- __m128i a0 = _mm_load_si128( (__m128i const *)tmp );
- for(unsigned i=0;i<8;i++) ((uint8_t*)tmp)[i] = b[i];
- __m128i b0 = _mm_load_si128( (__m128i const *)tmp );
- __m128i c0 = _gf2ext64_mul_sse( a0 , b0 );
-
- _mm_store_si128((__m128i*) tmp , c0 );
- for(unsigned i=0;i<8;i++) c[i] = ((uint8_t*)tmp)[i];
-#if 0
- __m128i a0 = _mm_load_si128( (__m128i const *)a );
- __m128i b0 = _mm_load_si128( (__m128i const *)b );
- __m128i c0 = _gf2ext64_mul_sse( a0 , b0 );
-
- _mm_store_si128((__m128i*) c , c0 );
-#endif
-}
-
-
-static inline
-void gf2ext64_mul_2x2_sse( uint8_t * c , const uint8_t * a , const uint8_t * b )
-{
- __m128i a0a1 = _mm_load_si128( (__m128i const *)a );
- __m128i b0b1 = _mm_load_si128( (__m128i const *)b );
- __m128i c0c1 = _gf2ext64_mul_2x2_sse( a0a1 , b0b1 );
-
- _mm_store_si128((__m128i*) c , c0c1 );
-}
-
-static inline
-void gf2ext64_mul_4x4_avx2( uint8_t * c , const uint8_t * a , const uint8_t * b )
-{
- __m256i as = _mm256_load_si256( (__m256i const *)a );
- __m256i bs = _mm256_load_si256( (__m256i const *)b );
- __m256i cs = _gf2ext64_mul_4x4_avx2( as , bs );
-
- _mm256_store_si256((__m256i*) c , cs );
-}
-
-
-
-
-
-/////////////////////////////////////////////
-
-
-/// X^128 + X^7 + X^2 + X + 1
-/// 0x 8 7
-static const uint64_t _gf2ext128_reducer[2] __attribute__((aligned(32))) = {0x87ULL,0x0ULL};
-
-static inline
-__m128i _gf2ext128_reduce_sse( __m128i x0 , __m128i x128 )
-{
- __m128i reducer = _mm_load_si128( (__m128i const*)_gf2ext128_reducer );
- //__m128i *reducer = (__m128i *)_gf2ext128_reducer;
- __m128i x64 = _mm_clmulepi64_si128( x128 , reducer , 1 ); /// 0_32 , xx2_32 , xx1 , xx0
- x128 ^= _mm_shuffle_epi32( x64 , 0xfe ); // 0,0,0,xx2 ; 0xfe --> 3,3,3,2
- x0 ^= _mm_shuffle_epi32( x64 , 0x4f ); // xx1 , xx0 , 0 , 0 ; 0x4f --> 1,0,3,3 --> xx1,xx0,0,0
- x0 ^= _mm_clmulepi64_si128( x128 , reducer , 0 );
- return x0;
-}
-
-static inline
-__m128i _gf_aesgcm_reduce_sse( __m128i x0 , __m128i x128 )
-{
- //__m128i *mask_32 = (__m128i*) _low_32bit_on;
- __m128i mask_32 = _mm_setr_epi32(0xffffffff,0,0,0);
- __m128i tmp = _mm_srli_epi32(x128,31) ^ _mm_srli_epi32(x128,30) ^ _mm_srli_epi32(x128,25);
-
- __m128i tmp_rol_32 = _mm_shuffle_epi32(tmp,0x93);
- x128 ^= (mask_32)&tmp_rol_32;
- x0 ^= _mm_andnot_si128( mask_32 , tmp_rol_32 );
-
- x0 ^= x128 ^ _mm_slli_epi32( x128 , 1 ) ^ _mm_slli_epi32( x128 , 2 ) ^_mm_slli_epi32( x128 , 7 );
- return x0;
-}
-
-#define _MUL_128( c0,c2,a0,b0 ) \
-do {\
- __m128i tt = _mm_clmulepi64_si128( a0,b0 , 0x01 ); \
- c0 = _mm_clmulepi64_si128( a0,b0, 0 ); \
- c2 = _mm_clmulepi64_si128( a0,b0, 0x11 ); \
- tt ^= _mm_clmulepi64_si128( a0,b0 , 0x10 ); \
- c0 ^= _mm_slli_si128( tt , 8 ); \
- c2 ^= _mm_srli_si128( tt , 8 ); \
-} while(0)
-
-#define _MUL_128_KARATSUBA( c0,c1,a0,b0 ) \
-do {\
- c0 = _mm_clmulepi64_si128( a0,b0 , 0x00 ); \
- c1 = _mm_clmulepi64_si128( a0,b0 , 0x11 ); \
- __m128i _tt0 = a0^_mm_srli_si128(a0,8); \
- __m128i _tt1 = b0^_mm_srli_si128(b0,8); \
- __m128i _tt2 = _mm_clmulepi64_si128( _tt0, _tt1 , 0 )^c0^c1; \
- c0 ^= _mm_slli_si128( _tt2 , 8 ); \
- c1 ^= _mm_srli_si128( _tt2 , 8 ); \
-} while(0)
-
-
-static inline
-void gf2ext128_mul_sse( uint8_t * c , const uint8_t * a , const uint8_t * b )
-{
- __m128i a0 = _mm_load_si128( (__m128i const *)a );
- __m128i b0 = _mm_load_si128( (__m128i const *)b );
- __m128i c0,c128;
- _MUL_128_KARATSUBA( c0,c128, a0,b0 );
-
- __m128i c3 = _gf2ext128_reduce_sse( c0 , c128 );
- //__m128i c3 = _gf_aesgcm_reduce_sse( c0 , c128 );
- _mm_store_si128((__m128i*) c , c3 );
-}
-
-
-static inline
-__m128i _gf2ext128_mul_sse( __m128i a0 , __m128i b0 )
-{
- __m128i c0,c128;
- _MUL_128_KARATSUBA( c0,c128, a0,b0 );
- __m128i c3 = _gf2ext128_reduce_sse( c0 , c128 );
- return c3;
-}
-
-
-static inline
-__m256i _gf2ext128_mul_2x1_avx2( __m256i a0a1 , __m128i b0 )
-{
- __m128i a0 = _mm256_castsi256_si128(a0a1);
- __m128i a1 = _mm256_extracti128_si256(a0a1,1);
-
- __m128i c0,c128;
- __m128i d0,d128;
- _MUL_128_KARATSUBA( c0,c128, a0,b0 );
- _MUL_128_KARATSUBA( d0,d128, a1,b0 );
- __m128i c3 = _gf2ext128_reduce_sse( c0 , c128 );
- __m128i d3 = _gf2ext128_reduce_sse( d0 , d128 );
-
- __m256i r = _mm256_castsi128_si256(c3);
-
- return _mm256_inserti128_si256(r,d3,1);
-}
-
-
-
-////////////////////////////////////////////////////////////////////////////////////
-
-
-// s7 = x^64 + x^32 + x16 + x8 + x4 + x2 + x
-
-
-static const uint64_t _s7[2] __attribute__((aligned(32))) = {0x100010116ULL,0x1ULL};
-
-static inline
-__m256i div_s7( __m256i a )
-{
- __m128i r_s7 = _mm_load_si128( (__m128i const*)_s7 );
- __m128i a1 = _mm256_extracti128_si256( a, 1 );
- __m128i a0 = _mm256_castsi256_si128( a );
-
- __m128i a1h_s7 = _mm_clmulepi64_si128( a1 , r_s7 , 1 );
- a1 ^= _mm_srli_si128( a1^a1h_s7 , 8 );
- a0 ^= _mm_slli_si128( a1h_s7 , 8 );
-
- a0 ^= _mm_slli_si128( a1 , 8 );
- a0 ^= _mm_clmulepi64_si128( a1 , r_s7 , 0 );
-
- __m256i r = _mm256_castsi128_si256( a0 );
- return _mm256_inserti128_si256( r , a1 , 1 );
-}
-
-
-static inline
-__m256i exp_s7( __m256i a )
-{
- __m128i r_s7 = _mm_load_si128( (__m128i const*)_s7 );
- __m128i a1 = _mm256_extracti128_si256( a, 1 );
- __m128i a0 = _mm256_castsi256_si128( a );
-
- a0 ^= _mm_clmulepi64_si128( a1 , r_s7 , 0 );
- a0 ^= _mm_slli_si128( a1 , 8 );
- __m128i a1h_s7 = _mm_clmulepi64_si128( a1 , r_s7 , 1 );
- a0 ^= _mm_slli_si128( a1h_s7 , 8 );
- a1 ^= _mm_srli_si128( a1^a1h_s7 , 8 );
-
- __m256i r = _mm256_castsi128_si256( a0 );
- return _mm256_inserti128_si256( r , a1 , 1 );
-}
-
-
-#endif
-
diff --git a/run_test.sh b/run_test.sh
deleted file mode 100755
index 91a717b..0000000
--- a/run_test.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-./bitpolymul-test 15
-./bitpolymul-test 16
-./bitpolymul-test 17
-./bitpolymul-test 18
-./bitpolymul-test 19
-./bitpolymul-test 20
-./bitpolymul-test 21
-./bitpolymul-test 22
-./bitpolymul-test 23
diff --git a/transpose.h b/transpose.h
deleted file mode 100644
index ec12dbf..0000000
--- a/transpose.h
+++ /dev/null
@@ -1,623 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-#ifndef _TRANSPOSE_H_
-#define _TRANSPOSE_H_
-
-#include
-#include
-
-
-static inline
-void tr_ref_4x4_b8( uint8_t * _r , const uint8_t * a ) {
- uint8_t r[4*4*8] __attribute__((aligned(32)));
- for(unsigned j=0;j<4;j++) {
- for(unsigned i=0;i<8;i++) {
- r[j*32+i*4+0] = a[i*4+j+0];
- r[j*32+i*4+1] = a[i*4+j+32];
- r[j*32+i*4+2] = a[i*4+j+32*2];
- r[j*32+i*4+3] = a[i*4+j+32*3];
- }
- }
- for(unsigned i=0;i<4*4*8;i++) _r[i] = r[i];
-}
-
-
-static uint8_t _tr_4x4[32] __attribute__((aligned(32))) = {0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15 ,0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15};
-
-static inline
-void tr_avx2_4x4_b8( uint8_t * _r , const uint8_t * a ) {
-
- __m256i r0 = _mm256_load_si256( (__m256i*) a );
- __m256i r1 = _mm256_load_si256( (__m256i*) (a+32) );
- __m256i r2 = _mm256_load_si256( (__m256i*) (a+64) );
- __m256i r3 = _mm256_load_si256( (__m256i*) (a+96) );
-
- __m256i t0 = _mm256_shuffle_epi8( r0 , *(__m256i*)_tr_4x4 ); // 00,01,02,03
- __m256i t1 = _mm256_shuffle_epi8( r1 , *(__m256i*)_tr_4x4 ); // 10,11,12,13
- __m256i t2 = _mm256_shuffle_epi8( r2 , *(__m256i*)_tr_4x4 ); // 20,21,22,23
- __m256i t3 = _mm256_shuffle_epi8( r3 , *(__m256i*)_tr_4x4 ); // 30,31,32,33
-
- __m256i t01lo = _mm256_unpacklo_epi32( t0 , t1 ); // 00,10,01,11
- __m256i t01hi = _mm256_unpackhi_epi32( t0 , t1 ); // 02,12,03,13
- __m256i t23lo = _mm256_unpacklo_epi32( t2 , t3 ); // 20,30,21,31
- __m256i t23hi = _mm256_unpackhi_epi32( t2 , t3 ); // 22,32,23,33
-
- __m256i r01lo = _mm256_unpacklo_epi64( t01lo , t23lo ); // 00,10,20,30
- __m256i r01hi = _mm256_unpackhi_epi64( t01lo , t23lo ); // 01,11,21,31
- __m256i r23lo = _mm256_unpacklo_epi64( t01hi , t23hi ); // 02,12,22,32
- __m256i r23hi = _mm256_unpackhi_epi64( t01hi , t23hi ); // 03,13,23,33
-
- __m256i s0 = _mm256_shuffle_epi8( r01lo , *(__m256i*)_tr_4x4 );
- __m256i s1 = _mm256_shuffle_epi8( r01hi , *(__m256i*)_tr_4x4 );
- __m256i s2 = _mm256_shuffle_epi8( r23lo , *(__m256i*)_tr_4x4 );
- __m256i s3 = _mm256_shuffle_epi8( r23hi , *(__m256i*)_tr_4x4 );
-
- _mm256_store_si256( (__m256i*) _r , s0 );
- _mm256_store_si256( (__m256i*) (_r+32) , s1 );
- _mm256_store_si256( (__m256i*) (_r+64) , s2 );
- _mm256_store_si256( (__m256i*) (_r+96) , s3 );
-}
-
-static inline
-void transpose_4x4_b8( uint8_t * r , const uint8_t * a ) {
- tr_avx2_4x4_b8(r,a);
-}
-
-
-static inline
-void tr_16x16_b2_from_4x4_b8_1_4( uint8_t * r , const uint8_t * a ) {
-
- __m256i a0 = _mm256_load_si256( (__m256i*) a ); // 00,04,08,0c
- __m256i a4 = _mm256_load_si256( (__m256i*) (a+32*4) ); // 10,14,18,1c
- __m256i a8 = _mm256_load_si256( (__m256i*) (a+32*8) ); // 20,24,28,2c
- __m256i ac = _mm256_load_si256( (__m256i*) (a+32*12) ); // 30,34,38,3c
-
- __m256i a04l = _mm256_unpacklo_epi32( a0 , a4 ); // 00,10,04,14
- __m256i a04h = _mm256_unpackhi_epi32( a0 , a4 ); // 08,18,0c,1c
- __m256i a8cl = _mm256_unpacklo_epi32( a8 , ac ); // 20,30,24,34
- __m256i a8ch = _mm256_unpackhi_epi32( a8 , ac ); // 28,38,2c,3c
-
- __m256i b0 = _mm256_unpacklo_epi64( a04l , a8cl ); // 00,10,20,30
- __m256i b4 = _mm256_unpackhi_epi64( a04l , a8cl ); // 04,14,24,34
- __m256i b8 = _mm256_unpacklo_epi64( a04h , a8ch ); // 08,18,28,38
- __m256i bc = _mm256_unpackhi_epi64( a04h , a8ch ); // 0c,1c,2c,3c
-
- _mm256_store_si256( (__m256i*) (r+32*0) , b0 );
- _mm256_store_si256( (__m256i*) (r+32*4) , b4 );
- _mm256_store_si256( (__m256i*) (r+32*8) , b8 );
- _mm256_store_si256( (__m256i*) (r+32*12) , bc );
-}
-
-static inline
-void tr_16x16_b2_from_4x4_b8( uint8_t * r , const uint8_t * a ) {
- tr_16x16_b2_from_4x4_b8_1_4( r , a );
- tr_16x16_b2_from_4x4_b8_1_4( r+32 , a+32 );
- tr_16x16_b2_from_4x4_b8_1_4( r+32*2 , a+32*2 );
- tr_16x16_b2_from_4x4_b8_1_4( r+32*3 , a+32*3 );
-}
-
-static inline
-void tr_16x16_b2_avx2( uint8_t * r , const uint8_t * a ) {
- uint8_t temp[32*16] __attribute__((aligned(32)));
- for(unsigned i=0;i<4;i++) tr_avx2_4x4_b8( temp + i*32*4 , a + i*32*4 );
- tr_16x16_b2_from_4x4_b8_1_4( r , temp );
- tr_16x16_b2_from_4x4_b8_1_4( r+32 , temp+32 );
- tr_16x16_b2_from_4x4_b8_1_4( r+32*2 , temp+32*2 );
- tr_16x16_b2_from_4x4_b8_1_4( r+32*3 , temp+32*3 );
-}
-
-/////////////////////////////////////
-
-
-static inline
-void tr_32x32_from_4x4_b8_1_4( uint8_t * r , const uint8_t * a )
-{
- __m256i a0 = _mm256_load_si256( (__m256i*) a ); // 00,04,08,0c
- __m256i a4 = _mm256_load_si256( (__m256i*) (a+32*4) ); // 10,14,18,1c
- __m256i a8 = _mm256_load_si256( (__m256i*) (a+32*8) ); // 20,24,28,2c
- __m256i ac = _mm256_load_si256( (__m256i*) (a+32*12) ); // 30,34,38,3c
- __m256i a10 = _mm256_load_si256( (__m256i*) (a+32*16) );
- __m256i a14 = _mm256_load_si256( (__m256i*) (a+32*20) );
- __m256i a18 = _mm256_load_si256( (__m256i*) (a+32*24) );
- __m256i a1c = _mm256_load_si256( (__m256i*) (a+32*28) );
-
- __m256i a04l = _mm256_unpacklo_epi32( a0 , a4 ); // 00,10,04,14
- __m256i a04h = _mm256_unpackhi_epi32( a0 , a4 ); // 08,18,0c,1c
- __m256i a8cl = _mm256_unpacklo_epi32( a8 , ac ); // 20,30,24,34
- __m256i a8ch = _mm256_unpackhi_epi32( a8 , ac ); // 28,38,2c,3c
- __m256i a1014l = _mm256_unpacklo_epi32( a10 , a14 );
- __m256i a1014h = _mm256_unpackhi_epi32( a10 , a14 );
- __m256i a181cl = _mm256_unpacklo_epi32( a18 , a1c );
- __m256i a181ch = _mm256_unpackhi_epi32( a18 , a1c );
-
- __m256i b0 = _mm256_unpacklo_epi64( a04l , a8cl ); // 00,10,20,30
- __m256i b4 = _mm256_unpackhi_epi64( a04l , a8cl ); // 04,14,24,34
- __m256i b8 = _mm256_unpacklo_epi64( a04h , a8ch ); // 08,18,28,38
- __m256i bc = _mm256_unpackhi_epi64( a04h , a8ch ); // 0c,1c,2c,3c
- __m256i b10 = _mm256_unpacklo_epi64( a1014l , a181cl );
- __m256i b14 = _mm256_unpackhi_epi64( a1014l , a181cl );
- __m256i b18 = _mm256_unpacklo_epi64( a1014h , a181ch );
- __m256i b1c = _mm256_unpackhi_epi64( a1014h , a181ch );
-
- __m256i c0 = _mm256_permute2x128_si256( b0 , b10 , 0x20 );
- __m256i c10 = _mm256_permute2x128_si256( b0 , b10 , 0x31 );
- __m256i c4 = _mm256_permute2x128_si256( b4 , b14 , 0x20 );
- __m256i c14 = _mm256_permute2x128_si256( b4 , b14 , 0x31 );
- __m256i c8 = _mm256_permute2x128_si256( b8 , b18 , 0x20 );
- __m256i c18 = _mm256_permute2x128_si256( b8 , b18 , 0x31 );
- __m256i cc = _mm256_permute2x128_si256( bc , b1c , 0x20 );
- __m256i c1c = _mm256_permute2x128_si256( bc , b1c , 0x31 );
-
- _mm256_store_si256( (__m256i*) (r+32*0) , c0 );
- _mm256_store_si256( (__m256i*) (r+32*4) , c4 );
- _mm256_store_si256( (__m256i*) (r+32*8) , c8 );
- _mm256_store_si256( (__m256i*) (r+32*12) , cc );
- _mm256_store_si256( (__m256i*) (r+32*16) , c10 );
- _mm256_store_si256( (__m256i*) (r+32*20) , c14 );
- _mm256_store_si256( (__m256i*) (r+32*24) , c18 );
- _mm256_store_si256( (__m256i*) (r+32*28) , c1c );
-}
-
-static inline
-void tr_32x32_from_4x4_b8( uint8_t * r , const uint8_t * a ) {
- tr_32x32_from_4x4_b8_1_4( r , a );
- tr_32x32_from_4x4_b8_1_4( r+32 , a+32 );
- tr_32x32_from_4x4_b8_1_4( r+32*2 , a+32*2 );
- tr_32x32_from_4x4_b8_1_4( r+32*3 , a+32*3 );
-}
-
-/////////////////////////////////
-
-
-static inline
-void tr_4x4_b8_from_32x32_1_4( uint8_t * r , const uint8_t * a )
-{
- __m256i b0 = _mm256_load_si256( (__m256i*) a ); // 00,04,08,0c
- __m256i b4 = _mm256_load_si256( (__m256i*) (a+32*4) ); // 10,14,18,1c
- __m256i b8 = _mm256_load_si256( (__m256i*) (a+32*8) ); // 20,24,28,2c
- __m256i bc = _mm256_load_si256( (__m256i*) (a+32*12) ); // 30,34,38,3c
- __m256i b10 = _mm256_load_si256( (__m256i*) (a+32*16) );
- __m256i b14 = _mm256_load_si256( (__m256i*) (a+32*20) );
- __m256i b18 = _mm256_load_si256( (__m256i*) (a+32*24) );
- __m256i b1c = _mm256_load_si256( (__m256i*) (a+32*28) );
-
- __m256i a0 = _mm256_permute2x128_si256( b0 , b10 , 0x20 );
- __m256i a10 = _mm256_permute2x128_si256( b0 , b10 , 0x31 );
- __m256i a4 = _mm256_permute2x128_si256( b4 , b14 , 0x20 );
- __m256i a14 = _mm256_permute2x128_si256( b4 , b14 , 0x31 );
- __m256i a8 = _mm256_permute2x128_si256( b8 , b18 , 0x20 );
- __m256i a18 = _mm256_permute2x128_si256( b8 , b18 , 0x31 );
- __m256i ac = _mm256_permute2x128_si256( bc , b1c , 0x20 );
- __m256i a1c = _mm256_permute2x128_si256( bc , b1c , 0x31 );
-
- __m256i a04l = _mm256_unpacklo_epi32( a0 , a4 ); // 00,10,04,14
- __m256i a04h = _mm256_unpackhi_epi32( a0 , a4 ); // 08,18,0c,1c
- __m256i a8cl = _mm256_unpacklo_epi32( a8 , ac ); // 20,30,24,34
- __m256i a8ch = _mm256_unpackhi_epi32( a8 , ac ); // 28,38,2c,3c
- __m256i a1014l = _mm256_unpacklo_epi32( a10 , a14 );
- __m256i a1014h = _mm256_unpackhi_epi32( a10 , a14 );
- __m256i a181cl = _mm256_unpacklo_epi32( a18 , a1c );
- __m256i a181ch = _mm256_unpackhi_epi32( a18 , a1c );
-
- __m256i k0 = _mm256_unpacklo_epi64( a04l , a8cl ); // 00,10,20,30
- __m256i k4 = _mm256_unpackhi_epi64( a04l , a8cl ); // 04,14,24,34
- __m256i k8 = _mm256_unpacklo_epi64( a04h , a8ch ); // 08,18,28,38
- __m256i kc = _mm256_unpackhi_epi64( a04h , a8ch ); // 0c,1c,2c,3c
- __m256i k10 = _mm256_unpacklo_epi64( a1014l , a181cl );
- __m256i k14 = _mm256_unpackhi_epi64( a1014l , a181cl );
- __m256i k18 = _mm256_unpacklo_epi64( a1014h , a181ch );
- __m256i k1c = _mm256_unpackhi_epi64( a1014h , a181ch );
-
- _mm256_store_si256( (__m256i*) (r+32*0) , k0 );
- _mm256_store_si256( (__m256i*) (r+32*4) , k4 );
- _mm256_store_si256( (__m256i*) (r+32*8) , k8 );
- _mm256_store_si256( (__m256i*) (r+32*12) , kc );
- _mm256_store_si256( (__m256i*) (r+32*16) , k10 );
- _mm256_store_si256( (__m256i*) (r+32*20) , k14 );
- _mm256_store_si256( (__m256i*) (r+32*24) , k18 );
- _mm256_store_si256( (__m256i*) (r+32*28) , k1c );
-}
-
-
-static inline
-void tr_4x4_b8_from_32x32( uint8_t * r , const uint8_t * a ) {
- tr_4x4_b8_from_32x32_1_4( r , a );
- tr_4x4_b8_from_32x32_1_4( r+32 , a+32 );
- tr_4x4_b8_from_32x32_1_4( r+32*2 , a+32*2 );
- tr_4x4_b8_from_32x32_1_4( r+32*3 , a+32*3 );
-}
-
-
-
-//////////////////////////////////////
-
-static inline
-void tr_ref_16x16( uint8_t * _r , const uint8_t * a ) {
- uint8_t r[16*16] __attribute__((aligned(32)));
- for(unsigned j=0;j<16;j++)
- for(unsigned k=0;k<16;k++) r[j*16+k] = a[k*16+j];
- for(unsigned i=0;i<16*16;i++) _r[i] = r[i];
-}
-
-//////////////////////////////////////
-
-static uint64_t gath_ref_16x32[4] __attribute__((aligned(32))) = {0,1*8,16*16,16*16+8 };
-
-static inline
-void tr_ref_16x32( uint8_t * r , const uint8_t * a )
-{
- uint8_t tr2[16*16*2] __attribute__((aligned(32)));
- tr_ref_16x16( tr2 , a );
- tr_ref_16x16( tr2+(16*16) , a+(16*16) );
-
- _mm256_store_si256( (__m256i*)(r) , _mm256_i64gather_epi64( (long long const*)tr2 , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+32) , _mm256_i64gather_epi64( (long long const*)(tr2+16) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+64) , _mm256_i64gather_epi64( (long long const*)(tr2+32) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+96) , _mm256_i64gather_epi64( (long long const*)(tr2+48) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+128) , _mm256_i64gather_epi64( (long long const*)(tr2+64) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+160) , _mm256_i64gather_epi64( (long long const*)(tr2+80) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+192) , _mm256_i64gather_epi64( (long long const*)(tr2+96) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+224) , _mm256_i64gather_epi64( (long long const*)(tr2+112) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+256) , _mm256_i64gather_epi64( (long long const*)(tr2+128) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+288) , _mm256_i64gather_epi64( (long long const*)(tr2+144) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+320) , _mm256_i64gather_epi64( (long long const*)(tr2+160) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+352) , _mm256_i64gather_epi64( (long long const*)(tr2+176) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+384) , _mm256_i64gather_epi64( (long long const*)(tr2+192) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+416) , _mm256_i64gather_epi64( (long long const*)(tr2+208) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+448) , _mm256_i64gather_epi64( (long long const*)(tr2+224) , *(__m256i*)gath_ref_16x32 , 1 ) );
- _mm256_store_si256( (__m256i*)(r+480) , _mm256_i64gather_epi64( (long long const*)(tr2+240) , *(__m256i*)gath_ref_16x32 , 1 ) );
-}
-
-static inline
-void transpose_16x32( uint8_t * r , const uint8_t * a )
-{
- tr_ref_16x32( r , a );
-}
-
-#if 0
-static uint64_t gath_32x16[4] __attribute__((aligned(32))) = {0, 8 , 32 , 40};
-#endif
-
-static inline
-void transpose_32x16( uint8_t * r , const uint8_t * a )
-{
-#if 1
- uint8_t tr2[16*16*2] __attribute__((aligned(32)));
- for(unsigned j=0;j<32;j++)
- for(unsigned k=0;k<16;k++) tr2[j*16+k] = a[k*32+j];
- for(unsigned i=0;i<32*16;i++) r[i] = tr2[i];
-#else
- uint8_t tr2[16*16*2] __attribute__((aligned(32)));
- _mm256_store_si256( (__m256i*)(tr2+0 ) , _mm256_i64gather_epi64( (long long const*)(a + 0) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+32) , _mm256_i64gather_epi64( (long long const*)(a + 16) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+64) , _mm256_i64gather_epi64( (long long const*)(a + 32) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+96) , _mm256_i64gather_epi64( (long long const*)(a + 48) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+128) , _mm256_i64gather_epi64( (long long const*)(a + 64) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+160) , _mm256_i64gather_epi64( (long long const*)(a + 80) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+192) , _mm256_i64gather_epi64( (long long const*)(a + 96) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+224) , _mm256_i64gather_epi64( (long long const*)(a + 112) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+256) , _mm256_i64gather_epi64( (long long const*)(a + 128) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+288) , _mm256_i64gather_epi64( (long long const*)(a + 144) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+320) , _mm256_i64gather_epi64( (long long const*)(a + 160) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+352) , _mm256_i64gather_epi64( (long long const*)(a + 176) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+384) , _mm256_i64gather_epi64( (long long const*)(a + 192) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+416) , _mm256_i64gather_epi64( (long long const*)(a + 208) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+448) , _mm256_i64gather_epi64( (long long const*)(a + 224) , *(__m256i*)gath_32x16 , 1 ) );
- _mm256_store_si256( (__m256i*)(tr2+480) , _mm256_i64gather_epi64( (long long const*)(a + 240) , *(__m256i*)gath_32x16 , 1 ) );
-
- tr_ref_16x16( r , tr2 );
- tr_ref_16x16( r+16*16 , tr2+16*16 );
-#endif
-}
-
-
-////////////////////////////////////////////
-
-
-static inline
-void tr_8x8_b4_avx2( uint8_t * _r , const uint8_t * a , const uint64_t mem_len ) {
-/// code of 4x4_b8
- __m256i r0 = _mm256_load_si256( (__m256i*) a );
- __m256i r1 = _mm256_load_si256( (__m256i*) (a+mem_len*1) );
- __m256i r2 = _mm256_load_si256( (__m256i*) (a+mem_len*2) );
- __m256i r3 = _mm256_load_si256( (__m256i*) (a+mem_len*3) );
-
- __m256i t0 = _mm256_shuffle_epi8( r0 , *(__m256i*)_tr_4x4 ); // 00,01,02,03
- __m256i t1 = _mm256_shuffle_epi8( r1 , *(__m256i*)_tr_4x4 ); // 10,11,12,13
- __m256i t2 = _mm256_shuffle_epi8( r2 , *(__m256i*)_tr_4x4 ); // 20,21,22,23
- __m256i t3 = _mm256_shuffle_epi8( r3 , *(__m256i*)_tr_4x4 ); // 30,31,32,33
-
- __m256i t01lo = _mm256_unpacklo_epi32( t0 , t1 ); // 00,10,01,11
- __m256i t01hi = _mm256_unpackhi_epi32( t0 , t1 ); // 02,12,03,13
- __m256i t23lo = _mm256_unpacklo_epi32( t2 , t3 ); // 20,30,21,31
- __m256i t23hi = _mm256_unpackhi_epi32( t2 , t3 ); // 22,32,23,33
-
- __m256i r01lo = _mm256_unpacklo_epi64( t01lo , t23lo ); // 00,10,20,30
- __m256i r01hi = _mm256_unpackhi_epi64( t01lo , t23lo ); // 01,11,21,31
- __m256i r23lo = _mm256_unpacklo_epi64( t01hi , t23hi ); // 02,12,22,32
- __m256i r23hi = _mm256_unpackhi_epi64( t01hi , t23hi ); // 03,13,23,33
-
- __m256i s0 = _mm256_shuffle_epi8( r01lo , *(__m256i*)_tr_4x4 );
- __m256i s1 = _mm256_shuffle_epi8( r01hi , *(__m256i*)_tr_4x4 );
- __m256i s2 = _mm256_shuffle_epi8( r23lo , *(__m256i*)_tr_4x4 );
- __m256i s3 = _mm256_shuffle_epi8( r23hi , *(__m256i*)_tr_4x4 );
-
-/// repeat 4x4_b8
- r0 = _mm256_load_si256( (__m256i*) (a+mem_len*4) );
- r1 = _mm256_load_si256( (__m256i*) (a+mem_len*5) );
- r2 = _mm256_load_si256( (__m256i*) (a+mem_len*6) );
- r3 = _mm256_load_si256( (__m256i*) (a+mem_len*7) );
-
- t0 = _mm256_shuffle_epi8( r0 , *(__m256i*)_tr_4x4 ); // 00,01,02,03
- t1 = _mm256_shuffle_epi8( r1 , *(__m256i*)_tr_4x4 ); // 10,11,12,13
- t2 = _mm256_shuffle_epi8( r2 , *(__m256i*)_tr_4x4 ); // 20,21,22,23
- t3 = _mm256_shuffle_epi8( r3 , *(__m256i*)_tr_4x4 ); // 30,31,32,33
-
- t01lo = _mm256_unpacklo_epi32( t0 , t1 ); // 00,10,01,11
- t01hi = _mm256_unpackhi_epi32( t0 , t1 ); // 02,12,03,13
- t23lo = _mm256_unpacklo_epi32( t2 , t3 ); // 20,30,21,31
- t23hi = _mm256_unpackhi_epi32( t2 , t3 ); // 22,32,23,33
-
- r01lo = _mm256_unpacklo_epi64( t01lo , t23lo ); // 00,10,20,30
- r01hi = _mm256_unpackhi_epi64( t01lo , t23lo ); // 01,11,21,31
- r23lo = _mm256_unpacklo_epi64( t01hi , t23hi ); // 02,12,22,32
- r23hi = _mm256_unpackhi_epi64( t01hi , t23hi ); // 03,13,23,33
-
- __m256i s4 = _mm256_shuffle_epi8( r01lo , *(__m256i*)_tr_4x4 );
- __m256i s5 = _mm256_shuffle_epi8( r01hi , *(__m256i*)_tr_4x4 );
- __m256i s6 = _mm256_shuffle_epi8( r23lo , *(__m256i*)_tr_4x4 );
- __m256i s7 = _mm256_shuffle_epi8( r23hi , *(__m256i*)_tr_4x4 );
-
-/// transpose s0,..., s7
- t0 = _mm256_unpacklo_epi32( s0 , s4 ); // s0_0 , s4_0 , s0_1 , s4_1
- t1 = _mm256_unpackhi_epi32( s0 , s4 ); // s0_2 , s4_2 , s0_3 , s4_3
- s0 = _mm256_unpacklo_epi64( t0 , t1 ); // s0_0 , s4_0 , s0_2 , s4_2
- s4 = _mm256_unpackhi_epi64( t0 , t1 ); // s0_1 , s4_1 , s0_3 , s4_3
-
- t2 = _mm256_unpacklo_epi32( s1 , s5 );
- t3 = _mm256_unpackhi_epi32( s1 , s5 );
- s1 = _mm256_unpacklo_epi64( t2 , t3 );
- s5 = _mm256_unpackhi_epi64( t2 , t3 );
-
- t0 = _mm256_unpacklo_epi32( s2 , s6 );
- t1 = _mm256_unpackhi_epi32( s2 , s6 );
- s2 = _mm256_unpacklo_epi64( t0 , t1 );
- s6 = _mm256_unpackhi_epi64( t0 , t1 );
-
- t2 = _mm256_unpacklo_epi32( s3 , s7 );
- t3 = _mm256_unpackhi_epi32( s3 , s7 );
- s3 = _mm256_unpacklo_epi64( t2 , t3 );
- s7 = _mm256_unpackhi_epi64( t2 , t3 );
-
- _mm256_store_si256( (__m256i*) _r , s0 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*1) , s1 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*2) , s2 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*3) , s3 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*4) , s4 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*5) , s5 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*6) , s6 );
- _mm256_store_si256( (__m256i*) (_r+mem_len*7) , s7 );
-}
-
-static inline
-void transpose_8x8_b4_avx2( uint8_t * _r , const uint8_t * a ) {
-#if 0
- tr_8x8_b4_avx2(_r,a,32);
-#else
- __m256i a0 = _mm256_load_si256( (__m256i*) a );
- __m256i a1 = _mm256_load_si256( (__m256i*) (a+32*1) );
- __m256i a2 = _mm256_load_si256( (__m256i*) (a+32*2) );
- __m256i a3 = _mm256_load_si256( (__m256i*) (a+32*3) );
- __m256i a4 = _mm256_load_si256( (__m256i*) (a+32*4) );
- __m256i a5 = _mm256_load_si256( (__m256i*) (a+32*5) );
- __m256i a6 = _mm256_load_si256( (__m256i*) (a+32*6) );
- __m256i a7 = _mm256_load_si256( (__m256i*) (a+32*7) );
-
- __m256i t0,t1,t2,t3;
- t0 = _mm256_unpacklo_epi32( a0 , a4 );
- t1 = _mm256_unpackhi_epi32( a0 , a4 );
- a0 = _mm256_unpacklo_epi64( t0 , t1 );
- a4 = _mm256_unpackhi_epi64( t0 , t1 );
-
- t2 = _mm256_unpacklo_epi32( a1 , a5 );
- t3 = _mm256_unpackhi_epi32( a1 , a5 );
- a1 = _mm256_unpacklo_epi64( t2 , t3 );
- a5 = _mm256_unpackhi_epi64( t2 , t3 );
-
- t0 = _mm256_unpacklo_epi32( a2 , a6 );
- t1 = _mm256_unpackhi_epi32( a2 , a6 );
- a2 = _mm256_unpacklo_epi64( t0 , t1 );
- a6 = _mm256_unpackhi_epi64( t0 , t1 );
-
- t2 = _mm256_unpacklo_epi32( a3 , a7 );
- t3 = _mm256_unpackhi_epi32( a3 , a7 );
- a3 = _mm256_unpacklo_epi64( t2 , t3 );
- a7 = _mm256_unpackhi_epi64( t2 , t3 );
-
-/// code of 4x4_b8
- t0 = _mm256_shuffle_epi8( a0 , *(__m256i*)_tr_4x4 ); // 00,01,02,03
- t1 = _mm256_shuffle_epi8( a1 , *(__m256i*)_tr_4x4 ); // 10,11,12,13
- t2 = _mm256_shuffle_epi8( a2 , *(__m256i*)_tr_4x4 ); // 20,21,22,23
- t3 = _mm256_shuffle_epi8( a3 , *(__m256i*)_tr_4x4 ); // 30,31,32,33
-
- __m256i t01lo = _mm256_unpacklo_epi32( t0 , t1 ); // 00,10,01,11
- __m256i t01hi = _mm256_unpackhi_epi32( t0 , t1 ); // 02,12,03,13
- __m256i t23lo = _mm256_unpacklo_epi32( t2 , t3 ); // 20,30,21,31
- __m256i t23hi = _mm256_unpackhi_epi32( t2 , t3 ); // 22,32,23,33
-
- __m256i r01lo = _mm256_unpacklo_epi64( t01lo , t23lo ); // 00,10,20,30
- __m256i r01hi = _mm256_unpackhi_epi64( t01lo , t23lo ); // 01,11,21,31
- __m256i r23lo = _mm256_unpacklo_epi64( t01hi , t23hi ); // 02,12,22,32
- __m256i r23hi = _mm256_unpackhi_epi64( t01hi , t23hi ); // 03,13,23,33
-
- __m256i s0 = _mm256_shuffle_epi8( r01lo , *(__m256i*)_tr_4x4 );
- __m256i s1 = _mm256_shuffle_epi8( r01hi , *(__m256i*)_tr_4x4 );
- __m256i s2 = _mm256_shuffle_epi8( r23lo , *(__m256i*)_tr_4x4 );
- __m256i s3 = _mm256_shuffle_epi8( r23hi , *(__m256i*)_tr_4x4 );
-
-/// repeat 4x4_b8
- t0 = _mm256_shuffle_epi8( a4 , *(__m256i*)_tr_4x4 ); // 00,01,02,03
- t1 = _mm256_shuffle_epi8( a5 , *(__m256i*)_tr_4x4 ); // 10,11,12,13
- t2 = _mm256_shuffle_epi8( a6 , *(__m256i*)_tr_4x4 ); // 20,21,22,23
- t3 = _mm256_shuffle_epi8( a7 , *(__m256i*)_tr_4x4 ); // 30,31,32,33
-
- t01lo = _mm256_unpacklo_epi32( t0 , t1 ); // 00,10,01,11
- t01hi = _mm256_unpackhi_epi32( t0 , t1 ); // 02,12,03,13
- t23lo = _mm256_unpacklo_epi32( t2 , t3 ); // 20,30,21,31
- t23hi = _mm256_unpackhi_epi32( t2 , t3 ); // 22,32,23,33
-
- r01lo = _mm256_unpacklo_epi64( t01lo , t23lo ); // 00,10,20,30
- r01hi = _mm256_unpackhi_epi64( t01lo , t23lo ); // 01,11,21,31
- r23lo = _mm256_unpacklo_epi64( t01hi , t23hi ); // 02,12,22,32
- r23hi = _mm256_unpackhi_epi64( t01hi , t23hi ); // 03,13,23,33
-
- __m256i s4 = _mm256_shuffle_epi8( r01lo , *(__m256i*)_tr_4x4 );
- __m256i s5 = _mm256_shuffle_epi8( r01hi , *(__m256i*)_tr_4x4 );
- __m256i s6 = _mm256_shuffle_epi8( r23lo , *(__m256i*)_tr_4x4 );
- __m256i s7 = _mm256_shuffle_epi8( r23hi , *(__m256i*)_tr_4x4 );
-
- _mm256_store_si256( (__m256i*) _r , s0 );
- _mm256_store_si256( (__m256i*) (_r+32*1) , s1 );
- _mm256_store_si256( (__m256i*) (_r+32*2) , s2 );
- _mm256_store_si256( (__m256i*) (_r+32*3) , s3 );
- _mm256_store_si256( (__m256i*) (_r+32*4) , s4 );
- _mm256_store_si256( (__m256i*) (_r+32*5) , s5 );
- _mm256_store_si256( (__m256i*) (_r+32*6) , s6 );
- _mm256_store_si256( (__m256i*) (_r+32*7) , s7 );
-#endif
-}
-
-
-
-static inline
-void transpose_8x8_h4zero_b4_avx2( uint8_t * _r , const uint8_t * a ) {
- __m256i a0 = _mm256_load_si256( (__m256i*) a );
- __m256i a1 = _mm256_load_si256( (__m256i*) (a+32*1) );
- __m256i a2 = _mm256_load_si256( (__m256i*) (a+32*2) );
- __m256i a3 = _mm256_load_si256( (__m256i*) (a+32*3) );
- __m256i a4 = _mm256_load_si256( (__m256i*) (a+32*4) );
- __m256i a5 = _mm256_load_si256( (__m256i*) (a+32*5) );
- __m256i a6 = _mm256_load_si256( (__m256i*) (a+32*6) );
- __m256i a7 = _mm256_load_si256( (__m256i*) (a+32*7) );
-
- __m256i t0,t1,t2,t3;
- t0 = _mm256_unpacklo_epi32( a0 , a4 );
- t1 = _mm256_unpackhi_epi32( a0 , a4 );
- a0 = _mm256_unpacklo_epi64( t0 , t1 );
-
- t2 = _mm256_unpacklo_epi32( a1 , a5 );
- t3 = _mm256_unpackhi_epi32( a1 , a5 );
- a1 = _mm256_unpacklo_epi64( t2 , t3 );
-
- t0 = _mm256_unpacklo_epi32( a2 , a6 );
- t1 = _mm256_unpackhi_epi32( a2 , a6 );
- a2 = _mm256_unpacklo_epi64( t0 , t1 );
-
- t2 = _mm256_unpacklo_epi32( a3 , a7 );
- t3 = _mm256_unpackhi_epi32( a3 , a7 );
- a3 = _mm256_unpacklo_epi64( t2 , t3 );
-
-/// code of 4x4_b8
- t0 = _mm256_shuffle_epi8( a0 , *(__m256i*)_tr_4x4 ); // 00,01,02,03
- t1 = _mm256_shuffle_epi8( a1 , *(__m256i*)_tr_4x4 ); // 10,11,12,13
- t2 = _mm256_shuffle_epi8( a2 , *(__m256i*)_tr_4x4 ); // 20,21,22,23
- t3 = _mm256_shuffle_epi8( a3 , *(__m256i*)_tr_4x4 ); // 30,31,32,33
-
- __m256i t01lo = _mm256_unpacklo_epi32( t0 , t1 ); // 00,10,01,11
- __m256i t01hi = _mm256_unpackhi_epi32( t0 , t1 ); // 02,12,03,13
- __m256i t23lo = _mm256_unpacklo_epi32( t2 , t3 ); // 20,30,21,31
- __m256i t23hi = _mm256_unpackhi_epi32( t2 , t3 ); // 22,32,23,33
-
- __m256i r01lo = _mm256_unpacklo_epi64( t01lo , t23lo ); // 00,10,20,30
- __m256i r01hi = _mm256_unpackhi_epi64( t01lo , t23lo ); // 01,11,21,31
- __m256i r23lo = _mm256_unpacklo_epi64( t01hi , t23hi ); // 02,12,22,32
- __m256i r23hi = _mm256_unpackhi_epi64( t01hi , t23hi ); // 03,13,23,33
-
- __m256i s0 = _mm256_shuffle_epi8( r01lo , *(__m256i*)_tr_4x4 );
- __m256i s1 = _mm256_shuffle_epi8( r01hi , *(__m256i*)_tr_4x4 );
- __m256i s2 = _mm256_shuffle_epi8( r23lo , *(__m256i*)_tr_4x4 );
- __m256i s3 = _mm256_shuffle_epi8( r23hi , *(__m256i*)_tr_4x4 );
-
- _mm256_store_si256( (__m256i*) _r , s0 );
- _mm256_store_si256( (__m256i*) (_r+32*1) , s1 );
- _mm256_store_si256( (__m256i*) (_r+32*2) , s2 );
- _mm256_store_si256( (__m256i*) (_r+32*3) , s3 );
-
-}
-
-
-
-
-#include "transpose_bit.h"
-
-
-
-static inline
-void tr_bit_8x8_b32_avx2( uint8_t * _r , const uint8_t * a ) {
- for(unsigned i=0;i<8;i++) {
- tr_bit_8x8_b4_avx( _r + (32*i) , a + (32*i) );
- }
-
- tr_8x8_b4_avx2( _r , _r , 32 );
-
- for(unsigned i=0;i<8;i++) {
- tr_bit_8x8_b4_avx( _r + (32*i) , _r + (32*i) );
- }
-}
-
-
-
-static inline
-void tr_bit_64x64_b4_avx2( uint8_t * _r , const uint8_t * a ) {
- for(unsigned i=0;i<8;i++) {
- tr_bit_8x8_b32_avx2( _r + (32*8*i) , a + (32*8*i) );
- }
-
- for(unsigned i=0;i<8;i++) {
- tr_8x8_b4_avx2( _r + 32*i , _r + 32*i , 32*8 );
- }
-}
-
-
-static inline
-void tr_bit_128x128_b2_avx2( uint8_t * _r , const uint8_t * a ) {
- tr_bit_64x64_b4_avx2( _r , a );
- tr_bit_64x64_b4_avx2( _r+64*32 , a+64*32 );
-
- for(unsigned i=0;i<64;i++) {
- __m256i m00_m01 = _mm256_load_si256( (__m256i*) (_r+32*i) ); // 00 , 01
- __m256i m10_m11 = _mm256_load_si256( (__m256i*) (_r+32*i+32*64) ); // 10 , 11
- __m256i t0 = _mm256_unpacklo_epi64( m00_m01 , m10_m11 ); // 00 , 10
- __m256i t1 = _mm256_unpackhi_epi64( m00_m01 , m10_m11 ); // 01 , 11
- _mm256_store_si256( (__m256i*) (_r+32*i) , t0 );
- _mm256_store_si256( (__m256i*) (_r+32*i+32*64) , t1 );
-
- }
-}
-
-
-
-
-
-
-
-#endif
-
-
diff --git a/transpose_bit.h b/transpose_bit.h
deleted file mode 100644
index d7c5ff1..0000000
--- a/transpose_bit.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-
-Code is borrowed from HOEVEN, LARRIEU, and LECERF.
-
-*/
-
-#ifndef _TRANSPOSE_BIT_H_
-#define _TRANSPOSE_BIT_H_
-
-#include
-#include
-
-
-
-static uint64_t _tr_bit_mask_4[4] __attribute__((aligned(32))) = {0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL,0x00000000f0f0f0f0ULL};
-static uint64_t _tr_bit_mask_2[4] __attribute__((aligned(32))) = {0x0000cccc0000ccccULL,0x0000cccc0000ccccULL,0x0000cccc0000ccccULL,0x0000cccc0000ccccULL};
-static uint64_t _tr_bit_mask_1[4] __attribute__((aligned(32))) = {0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL,0x00aa00aa00aa00aaULL};
-
-
-static inline
-__m256i tr_bit_8x8_b4_ymmx1( __m256i n ) {
- __m256i a;
-
- a = (_mm256_srli_epi64(n,28)^n)&(*(__m256i*)_tr_bit_mask_4); n ^= a;
- a = _mm256_slli_epi64(a,28); n ^= a;
- a = (_mm256_srli_epi64(n,14)^n)&(*(__m256i*)_tr_bit_mask_2); n ^= a;
- a = _mm256_slli_epi64(a,14); n ^= a;
- a = (_mm256_srli_epi64(n,7)^n)&(*(__m256i*)_tr_bit_mask_1); n ^= a;
- a = _mm256_slli_epi64(a,7); n ^= a;
-
- return n;
-}
-
-
-static inline
-void tr_bit_8x8_b4_avx( uint8_t * _r , const uint8_t * m ) {
-
- __m256i n = _mm256_load_si256( (__m256i*) m );
- __m256i r = tr_bit_8x8_b4_ymmx1( n );
- _mm256_store_si256( (__m256i*) _r , r );
-}
-
-
-
-#endif
-
-
diff --git a/trunc_btfy_tab.c b/trunc_btfy_tab.c
deleted file mode 100644
index 7ccd7e2..0000000
--- a/trunc_btfy_tab.c
+++ /dev/null
@@ -1,2351 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#include "stdint.h"
-
-
-
-
-uint64_t beta_mul_64 [2*128] __attribute__((aligned(32))) = {
-0x1,0x0,
-0x27f349141093e620,0x97e14e9448decae7,
-0x771a1494d77054ac,0xde34b71e0312848f,
-0xdeafe01fb241011,0xb1d31d60b6d7bc8f,
-0x249484a90e31ef88,0xd78f250953e96933,
-0x909bc29e826d7066,0xc3c007046fddeefa,
-0xcaff957ad3992010,0x2057e9ac7298d3eb,
-0x812cdd1aaf6f637e,0x12e402e16cb87ff,
-0xd1700ce51721220c,0xee558f30070e0c3d,
-0x61a6ea50178b40de,0xef91aaee46f9b12c,
-0x3cc4b7f9d4f8183f,0xffb4b5030153c513,
-0x1d5a817504a9614b,0xd6e0380005d79b55,
-0xbbe78d672fc17afe,0xaa755e03eb599308,
-0xbacff7b5da2d4dc8,0x3893f88cf1d8b9d8,
-0x509701100c19dd40,0x1027ea86550d3a4a,
-0xf2a17fc4f1b38192,0x85821b28658499f4,
-0xda8e23483a97853a,0x38f065e6ec77c32c,
-0x71aa4512e4d17a48,0x9b19c0697e63e597,
-0x579a529a6c27531c,0x1837dc34927a070c,
-0xd04da8bcca509fe,0x3fb127705dfcd0ae,
-0x8126c8f62ea9a442,0x48ae34776e9206cd,
-0x9ab26adf33a09b03,0x271246a69465234,
-0x39e51efde47d0d4c,0xfada9715799bd896,
-0x9fbbbfcc3f711744,0x342723809e59572a,
-0xba39ec5b7c011c77,0x8eed3748f24f4c71,
-0x73841061c8098499,0x9824d5741abb682d,
-0x3b33ca75e85ab465,0x249562545af45b33,
-0x456814efeaa19dc9,0x413ad31adbff42af,
-0x777fdb7900d3d7d7,0xe7a1fcbb738133f4,
-0x413ca20db613bcb1,0x9ef094ea8975e5da,
-0x84851801fe42af9d,0xa354057024702154,
-0x40672037e2a51e48,0x991f04ba87507ab7,
-0x5a70839fc81fb4c0,0xd35f0eb88cae752b,
-0xb7bc16ff3c497ce3,0x7470192c9ad0a0a2,
-0x53a3ec6052d187b,0x8604e75bd6d20e70,
-0x94302df687f68214,0x12f14476daa2fb97,
-0x82c068635c4dc7c5,0x614adf9e258cdda4,
-0xbda292ff893d3568,0xce79826cd6c65726,
-0x58cb9be1393fa3db,0x1c1cd90609568fe5,
-0xab7f53aeec82f4e0,0x535e75c5ce8d218e,
-0xfa064d9340b0f2fb,0xb6eb2f1b7a6b23ed,
-0x211a7bfda3651c83,0x27386deb9b2d3425,
-0x67d9e2b150b2bff6,0xf2159c5f14114bd9,
-0xce5f07612f3c52ca,0x6098cf23d70e40b6,
-0x971406df3d9cb7b5,0xcbb1fff5c22c1a34,
-0x78122774e35df18,0x46fe4ad7e254b2e,
-0xc206eb9e4e1d1549,0xe3d1828a986baf43,
-0xca4c9381702c9d71,0x8331573a516cab66,
-0xfc855a3d96d33183,0x7d6af3792d4e9935,
-0xac540cfcd040d548,0xe1dd429cbae41b95,
-0xc2290805bf846f1c,0x8adcb26beb71ec4f,
-0x1bbf36fe4767d716,0x6b4fcc753c59a164,
-0xaf590392b084a089,0xd68fd55025dfed19,
-0x229861c24fc21af3,0xd3ac3d55e3c3fc55,
-0xada7cb080bea7f5b,0x355577fadae81c5a,
-0x16aeb3de82c15ae5,0x48dc80037c27aa27,
-0xd91515cb53d1c421,0xf6636c29c12d5d92,
-0xbab2f444ab7a040e,0x48f27dd55afcf780,
-0x2d1f89c6ff2c0e05,0x3802147e1d005132,
-0xe6a8bac7288c2bf5,0xf975e8d8221f4e89,
-0x33b799951d4a4a14,0x6dce6b48904dc15c,
-0x8b9af2edf612cc3,0x7182c595d3e82b05,
-0x764a45526b6abbd8,0xa3068c6c48e849aa,
-0xcbb04e9547974bcc,0xd12f44a9264603a4,
-0xe3a3756c6efacfc4,0xf788c793e7244e9f,
-0x663efd859c10c22c,0x25065ed323ef00f2,
-0xb51df2de6c07299b,0x711d0ef4c8bccee4,
-0xbec88b1f3dde8a02,0x8f9e63ed255cd05e,
-0xfb395361f811807,0x5c2e3b2e98559956,
-0x8bbd4780b73c9fd8,0x5dc9f6282b04a4f,
-0x2d925219df8ea3a4,0x448cc0037d428972,
-0x77894c3c90ad97fd,0xdf8cb49c31f62d8c,
-0x72f3490e4d7dac6e,0xa704c85ecff81fb4,
-0x7ce2e7da483e9b7e,0xb6f897f6c913e66,
-0x463dd249ba184b7,0x9380f2a240dd4aa8,
-0x6ee8dc5f7057fd1,0x9305717c4aaaf1df,
-0xa07ff162f13af86e,0x61cf7524bdbc3b14,
-0x3561d304c885f299,0x15dcf54d9ed5d750,
-0x727661c772f02e9b,0x5dfc55213c8f3c7d,
-0xd07233170082ade6,0xf920f53e9b726db5,
-0xaca654f9d0aaae0d,0x68869b71bfa74038,
-0xf1771612f988bebf,0xc2e225aaff6867b0,
-0x8114907d2426edab,0xf6c9e4ba5dd44173,
-0x2b27a060df2a7e42,0x466c69dac1e4a203,
-0x26c591493ab400a6,0x5c78b93a829af95e,
-0xc723f6130ccf16aa,0x291343efe0de9730,
-0x956bd7b6c5ceb302,0xbfb67dd05c7859e8,
-0xe4ddd2092101d415,0x809be5bb79335cf5,
-0x87b0e14bf3828f0,0x845f633e96ff2a,
-0x3fee11b120ea35b4,0xfcbedf687fc693e0,
-0x702acbcd3e68afc,0x490bb89709ad2ec6,
-0x50da81a65d1f5ee8,0xc1ee4bbf75f1a13f,
-0xceb7d24ac297dad1,0x39dba9b90a44212c,
-0xd1e02303c09e26b3,0x2d85e933ea930fa7,
-0x120bc124ef560aa3,0x10b4d656c2349b72,
-0xec375c2e4287b407,0xe942a33ba44e843c,
-0x9ddbf2bf83d8324e,0xa656aec5c1b62dad,
-0x6e4ffe6ba3ea238d,0xbafb36eb6c474e16,
-0x3803efef2d980f04,0xab40a6734a52c408,
-0xcfd350c2b65412da,0xe9f462bec6864fc5,
-0x5f27fbd870189a2,0x242e8b05a153b674,
-0xa529cf153f5c9f17,0xa16cc6a6e1f2d2d8,
-0x86025185e2816c0e,0xe65a52324520795a,
-0xa5dfe6545c2e77a0,0xabe6f65522c8e0e2,
-0x95853616eeeb652,0xdad2d93ce1dce26,
-0xd64315edda50b6ea,0xe75ecc62193f1b6c,
-0x44bd9d1cd6fa986e,0xfa3a18a22cdb3ab9,
-0xaf42d12024dcffaa,0x788c76ff15e62a7a,
-0x498a3ac692966e2e,0x8e529220b0f801a0,
-0xd813bf6ae120178f,0x824e2da508810099,
-0x95a349169c82bbce,0x2873f1de6a87639c,
-0x747bb35e7057241a,0x8d4026dd47e43ae8,
-0xd54b2c5124f11910,0x1803f1f26aaa2bf5,
-0xd9a2e336210e4f59,0x46e23ae93dcde9e1,
-0x7d0429c3cc6d0fe8,0x707a38ce8c841da7,
-0xba7f39cfd6e06ec0,0x3acd1756b725043e,
-0x8388dd30b0d6989,0x11671b5832d2ffc9,
-0xf1fff1af2b10c9a8,0x1320ae24e20d09fd,
-0x8c41b19f89b27bc3,0x3021cf76a56fe146,
-0x6c700a1ee628b1f3,0xd80cfc2d2da35a48,
-0x652cf30703c3e8c4,0x546ad5084a06421b,
-0xa92d9f433849416e,0xcb29da19cca4f242,
-0x9e2d7d36f589a05a,0x79d2f2b767da7e38,
-0x4ddccc7bb4df38f9,0x4c0d593d582c3b7d,
-0x1d6a8915cbaf935,0x5853a3e438c30d75,
-0x4275586172b803ff,0x8a9c3c80880044a8,
-0x3de5637eab7356e7,0xdf4654cceb273085,
-0xff9141b4cd72945f,0xfbfc96eaf677f989,
-};
-
-uint64_t i_beta_mul_64 [2*128] __attribute__((aligned(32))) = {
-0x1, 0x0,
-0xecf66645c42f27d2, 0xbb9c4837f8fa748d,
-0xd5342e435bcfa36b, 0xddef560a099feb47,
-0x5fff2f2899754586, 0xffc52daa7378c96,
-0x9eea4735654e8b20, 0x7df7e1542629c8fa,
-0x9118fd4d23f814ee, 0xe35f69956f1beed5,
-0x143a922d810cab4e, 0xdcb7d7dfbda43579,
-0x7484979e45d5c6cd, 0x1c1baaeaf68343c1,
-0xbaea7da6950e0871, 0x61fa705346f16b81,
-0x95b959adba8f6c8e, 0xc7a3a46dd05f3cd1,
-0x38dd88b580502787, 0xf93a036ce958f29a,
-0x7b819c1bb59b8cb4, 0xd9b405fde33e0dd6,
-0x83c9948ca4735e2c, 0xfd1948c4689483a3,
-0xfb5cfe8645660435, 0x6366c931f55f9a92,
-0x4870975574b907ba, 0x52a836bde06eb23a,
-0xefa8fe1c1984bda, 0xa026a397fb3ef4b3,
-0x99eeb952d42732ac, 0x234ed6a5e3ef4647,
-0x67a8943a2c1ae3ce, 0x5a332b5df5b3e255,
-0xb7482f9c1ee213a3, 0x4753b3b4a4018cf4,
-0x206d5ed6cfe319d7, 0xa4a88a7346e16e4d,
-0xa629e78ff1a5914, 0x4680313320d6a236,
-0x1116bb56595fa626, 0x7711249cbff93818,
-0x865ecbee4ff8a28d, 0x10d5535602d65019,
-0x1273b09795f848b0, 0x25cdb63f30ec4456,
-0x32d9dae2c0de6438, 0xe9b5c80805104c82,
-0xfdaa16a3de2653e7, 0x604c7da1c92798f4,
-0x764c9ec62273383f, 0x4afdf087fe965d85,
-0xc7071589afe568f, 0x2ddcd18e4e3cfd,
-0x758875c0ad2199c2, 0x7954705201249cbe,
-0x9e8150d26d9e6f73, 0x951cbc5d7b26b436,
-0xe54e67583cf82552, 0xcf45b77c7c1d782f,
-0xc263dc59b1aeb82e, 0x68f678012b538423,
-0x5f4449293dbd9bc1, 0xe29034af1c490ded,
-0x41b03f81fb4bf94f, 0x9811b52d794d4156,
-0xffdad8173f1401b0, 0xc6608f909ff8d758,
-0x5fb0cca500e1fdb, 0x68ab63fbaa6996a0,
-0xf210b250c9a5f426, 0x56081cdfa5796682,
-0x15a9065bb77153c3, 0x1d1e13e659b2a4a7,
-0x8f3ea3eaec86e9a2, 0x658be53d57963278,
-0x79bd00a4780067de, 0x1e1969f2e1f5beab,
-0x542996c2bc830f6e, 0x5be2679739e79218,
-0x9bdafc579c8e83aa, 0x3f69ee8c7143c219,
-0x4dba819adf53648a, 0x64b9ac929afc3bf8,
-0xde2e3357f4dc068c, 0xf2ce240a73c7e750,
-0x40bb129a85016e35, 0x39d221bc71f9a711,
-0x3066d811d2e5d297, 0x34113e235727e97d,
-0x599e4c51b05ffa33, 0xbc2e0a80f5cd306a,
-0xc4359195a10bca7d, 0xc6c693ac63ee45e9,
-0xca9348d03c895dea, 0x88bb7ca14706c265,
-0x4ffcfbf90aa0b7d0, 0x34b65fce6f95803b,
-0x9fe7a02d7c89c2b2, 0xb40f58f09e4d6f24,
-0x9c078a08f0d3f289, 0x23b60c3e34f9e4e0,
-0x4e1a13f52b5220d3, 0xb2140d1ab7f90fbb,
-0xa75abffe2489b859, 0x1179b930fd6ea31c,
-0x8af69989f6b91088, 0xfb5f63b87c3af2b6,
-0xf842689103c7a411, 0xf12f57d304b13939,
-0xed2abec0cc27d63, 0x11c49965bfbff0d9,
-0xa7b077ec80059627, 0xf41db2c2c7df183c,
-0xeb5728051928e229, 0x440fcd482ec25955,
-0xf1f9d8ec2e47373b, 0xca0d757858cb098f,
-0xe4cf9d38d0c8b7a7, 0x2cd7ecedca99c859,
-0x923f1aa8638f75e7, 0x5ae12e5e241d4116,
-0xd424c70d43cf8045, 0x48be32f528a7d46e,
-0x547ad2eafaa25a2e, 0xb527b0e0258f85c6,
-0x1ddfd6b0e9c9cdf4, 0x34e37e650dfef9f5,
-0x2f05667382379817, 0xc33af18b93946155,
-0x350b8cb807932cc7, 0x9ec961f89b40f6ee,
-0xa413db16451b0d04, 0xdb14b5be55918a8e,
-0x7e1be604ea7be8e3, 0x4ac23e42b2434f30,
-0x39f3d54b3047dee1, 0x30f0c483a7fc3e61,
-0x3ed110cb4d43033b, 0x85e162d6fd3be59a,
-0xa91b8c40a875f358, 0x11baba7857c4b565,
-0x42ccf977843a80c9, 0xf8b4a6471b337bf5,
-0xc65aa1108ae8cc5, 0x5f47a69c02cabd57,
-0x40f3a3da7a173a67, 0x3722539af61115f,
-0x695dd08fac1d715f, 0xf630f66e7347bf6d,
-0x6633e1cfbfa27295, 0x205f094fc9cdd1ae,
-0x8f9b9b3498e3bfba, 0x158b02af3a93fd85,
-0x774ec817e02f691b, 0xfa9d66d55a72b7e5,
-0x3cf3c355e5ccd976, 0xdb13cb2cc7fba71f,
-0x39c06eea2d5b7643, 0x7373b211f41b59b2,
-0xc39c97c3383ac2ae, 0xdae530c1a1f6c6e4,
-0x68bc3cca80c985cc, 0x570a5b1fab90cd98,
-0xa9095f0f6b10e549, 0x1c48612a920a9fb5,
-0xb666602233849534, 0x3a990b3d0a2d1ff6,
-0xfbf6b8062428bd0e, 0xdbc1abd2d43ff417,
-0xfa53e4d7bbd0d0ad, 0x34c7d04666e0b811,
-0xa23b02c010cd6b4d, 0xf04dce88c8d32b69,
-0xc60e3c3e8cf9499a, 0xa58bc1bb03150f61,
-0xf5862a02e09cc659, 0x8c689afdab829b8f,
-0x1a3297b73ec2b031, 0xdc0f556b33393c79,
-0x6d40a192d2c9c259, 0xbc158ea111eeb0e9,
-0x9fa2b7630d0e199e, 0xbb7eb82b6f75f300,
-0xef4d13aebd63ad97, 0xa6335f30463c1d44,
-0x91dc2ecaf14f85e8, 0xfe2cec6d6d48be04,
-0xdc2de002ab499956, 0xf3e53ff202967cb3,
-0x4610fdac5d1e181c, 0x8b1959e2ef7d09b5,
-0xe8291ba53b0cea58, 0xb45647f7851d7b19,
-0x3cbfbdf5885e8ce3, 0xddc676d6f60084bd,
-0x48c9c1c68afdea75, 0x4ef7d1550f2fc17a,
-0xcffe0b1b8c6c6ebc, 0x8603d622de68945a,
-0x7252dbe2e4d68018, 0xf782a2247de03414,
-0x9b3d86323b3accb8, 0xa8a1a74814310775,
-0x387400ce373817a3, 0xbf9f4f7790e196a4,
-0xdcf152dd391a50f9, 0xabad14ceaa382f88,
-0x8fa6855aeb557415, 0x3e7be416061d9763,
-0x71025b3d69fedde, 0x90dc520eaace2dfe,
-0xb6a08214e4dfe898, 0xcf26c3ec4b5aaa08,
-0xdedc3a083e36247e, 0x9d8dc3ef51c41900,
-0xaae5c2ecd987432e, 0xe723dd51a8941f28,
-0x8622714ea6e04f9d, 0xc6291d9cce2d4cc3,
-0x2aacf7f940c55125, 0x4de6b7b8e3bc99cf,
-0xe958077b1c423172, 0x23dde025717eea9c,
-0x11e038b34e4bb1a3, 0xff5bb66ec8482057,
-0xd326b9e0c45fbabf, 0x56a07a4e4d203287,
-0x53a838b194a0cee2, 0x3c58bc86b5137988,
-0x33d83841c71bf7f4, 0xd72f7d005969a371,
-0x636a9442d1f2301a, 0x6013ff1b66aa8c11,
-0x723543c00b5eeb30, 0xb02fda581c8ef014,
-0xd2f6fd523150bedc, 0x7dffd0efcf4d2a89,
-0x4a1d6c71275230f, 0x2f764201914f7773,
-0xa2b24b4caeeedf59, 0xbc1b0ce96cb9f654,
-0x63e9117707ef973f, 0x2dfd29e472cdcc97,
-0x6d8f6750743fea86, 0x1d20bd0617f11f75,
-0x530b929d9a5f498e, 0x9f5871c2f3bec34e,
-0xe960746f0b2a0a98, 0x5bd0d86fe2e7b285,
-0xa1066c829343030b, 0xbda3a54466a22089,
-0x5a60106108199e1e, 0xc0ecdfb3df4bef20,
-};
-
-
-
-
-uint64_t beta_mul_64_bm4r [2*128*4] __attribute__((aligned(32))) = {
-0x8d8cadac21200100,0x9c9dbcbd30311011,
-0xfe769810ee668800,0x8008e66e9018f67e,
-0xb2b25454e6e60000,0xa2a24444f6f61010,
-0xbf50cf209f70ef00,0xdc33ac43fc138c63,
-0xe3e3707093930000,0xc7c75454b7b72424,
-0xc5f4a8995c6d3100,0xaa9bc7f633025e6f,
-0xc7c7d7d710100000,0x3c3c2c2cebebfbfb,
-0x5f51ddd38c820e00,0xf0fe727c232da1af,
-0x8080949414140000,0x8181959515150101,
-0x4de4d37a379ea900,0x57fec9602d84b31a,
-0x5d5d141449490000,0xa3a3eaeab7b7fefe,
-0xd357119546c28400,0xe8acc489b1f59dd,
-0xe9e91a1af3f30000,0x303f0f01919eaea,
-0xf0646bff0f9b9400,0xdc4847d323b7b82c,
-0x5050777727270000,0x5d5d7a7a2a2a0d0d,
-0x7e5aeecab4902400,0xffdb6f4b3511a581,
-0x68688f8fe7e70000,0xe7e7000068688f8f,
-0x2211d8ebc9fa3300,0xddee27143605ccff,
-0x4e4e8484caca0000,0xf2f238387676bcbc,
-0x543dbad387ee6900,0xd3ba3d540069ee87,
-0xcccc1212dede0000,0x1b1bc5c50909d7d7,
-0xac45719834dde900,0x678eba53ff1622cb,
-0x4b4b030348480000,0xfdfdb5b5fefeb6b6,
-0x4e1d21723c6f5300,0x580b37642a794516,
-0x8a8a1e1e94940000,0xeaea7e7ef4f46060,
-0xa1a8a5ac0d040900,0x8f868b82232a272e,
-0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d,
-0xcbeecce922072500,0x8bae8ca962476540,
-0xd5d53434e1e10000,0x606e7e73232d3d3,
-0x1897d8574fc08f00,0x36b9f67961eea12e,
-0x4949dede97970000,0xf8f86f6f2626b1b1,
-0x34e3f72014c3d700,0x35e2f62115c2d601,
-0xede1333fd2de0c00,0xa6aa78749995474b,
-0x7688be4036c8fe00,0xe41a2cd2a45a6c92,
-0x7a583a1862402200,0x1b395b7903214361,
-0xea90a7dd374d7a00,0x6b11265cb6ccfb81,
-0x5273d9f8aa8b2100,0xfbda7051032288a9,
-0xf534d819ec2dc100,0x46876baa5f9e72b3,
-0xd4c3c3d400171700,0xd0c7c7d004131304,
-0xf9d6230cf5da2f00,0x827d2fd042bdef1,
-0x4ca91cf9b550e500,0x39dc698cc0259075,
-0xc2a57710d2b56700,0x661b3d41671a3c4,
-0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81,
-0x7bf68c017af78d00,0x489f37e0588f27f,
-0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a,
-0xbf58709728cfe700,0x1ef9d136896e46a1,
-0x8c5ded3cb061d100,0x9140f021ad7ccc1d,
-0x51eaeb5001babb00,0xa31819a2f34849f2,
-0x23f2e13112c3d00,0x576a7b4644796855,
-0x9a92424ad0d80800,0x6e66b6be242cfcf4,
-0x7874c9c5bdb10c00,0xe3ef525e262a979b,
-0x1083a93a2ab99300,0x891a30a3b3200a99,
-0xa4aa5d53f7f90e00,0x737d8a84202ed9d7,
-0x8cd5540d81d85900,0x851d089055cdd84,
-0x4047060141460700,0x4542030444430205,
-0x4fa4be551af1eb00,0x2ac1db307f948e65,
-0xdded3303deee3000,0xdded3303deee3000,
-0x90a85868f8c0300,0x2122adaea7a42b28,
-0x901f3ab525aa8f00,0xa827028d1d92b738,
-0x4c12b4eaa6f85e00,0x5709aff1bde3451b,
-0x7025e1b4c4915500,0x90c501542471b5e0,
-0xc1b45227e6937500,0x4336d0a56411f782,
-0xfe1011ff01efee00,0x28c6c729d73938d6,
-0x8228ba109238aa00,0x7ad3f9517bd2f85,
-0x6e54261c72483a00,0x90aad8e28cb6c4fe,
-0xd4f0e4c41034200,0x490b4a0805470644,
-0xac29d653ff7a8500,0xa520df5af6738c09,
-0x3296a90d3f9ba400,0x2581be1a288cb317,
-0x61f6b02746d19700,0xc4531582e37432a5,
-0x74ddd47d09a0a900,0x5aca50c78d1d871,
-0xb288566cdee43a00,0x7e449aa01228f6cc,
-0xf9d7cae41d332e00,0xc6e8f5db220c113f,
-0xc088d29a5a124800,0x4b035911d199c38b,
-0xd4220bfd29dff600,0x18eec731e5133acc,
-0x3417715266452300,0xeecdab88bc9ff9da,
-0xbc74d61ea26ac800,0x3cb69a11dd577bf,
-0xbe30149a24aa8e00,0xba34109e20ae8a04,
-0x7157c3e594b22600,0xcaec785e2f099dbb,
-0xfc268d57ab71da00,0xf12b805aa67cd70d,
-0x22a3b8391b9a8100,0xbd3c27a684051e9f,
-0xb79b200cbb972c00,0x19358ea2153982ae,
-0x6fa25b96f934cd00,0x458871bcd31ee72a,
-0x21e2c40726e5c300,0xf13214d7f63513d0,
-0x8c8aded854520600,0xdbdd898f03055157,
-0x6e190d7a14637700,0x92e5f186e89f8bfc,
-0x4fdd099bd4469200,0x168450c28d1fcb59,
-0xec7e92927eec00,0x5db123cfcf23b15d,
-0x7e10177907696e00,0xe08e89e799f7f09e,
-0xbb5dd2348f69e600,0xcb2da244ff199670,
-0x87f62151d6a7700,0x88ffe2959deaf780,
-0x791cb9dca5c06500,0x5e3b9efb82e74227,
-0x87b3a39710243400,0xa49080b433071723,
-0xde2ec737e919f000,0x6f9f768658a841b1,
-0x5ab74dadf71ae00,0x228c53fdf8568927,
-0xbb832018a39b3800,0x84bc1f279ca4073f,
-0xb0f8b2fa4a024800,0x84cc86ce7e367c34,
-0x8bfc1265ee997700,0x4235dbac2750bec9,
-0xfb2c4a9d66b1d700,0xb36402d52ef99f48,
-0x2c30a8b498841c00,0xb1ad35290519819d,
-0xc41378af6bbcd700,0xda0d66b175a2c91e,
-0x52535b5a08090100,0xf3f2fafba9a8a0a1,
-0x82519142c013d300,0x27f434e765b676a5,
-0x5c2094e8b4c87c00,0xb6ca7e025e2296ea,
-0x4848fefeb6b60000,0xaaaa1c1c5454e2e2,
-0x4f142e753a615b00,0xa0fbc19ad58eb4ef,
-0x750c7801740d7900,0x423b4f36433a4e37,
-0x36da26cafc10ec00,0x22ce32dee804f814,
-0x61bac31879a2db00,0x419ae3385982fb20,
-0x8eb70a33bd843900,0xe6df625bd5ec5168,
-0xc6b9fa85433c7f00,0xa1de9de2245b1867,
-0xf248813bc973ba00,0xb70dc47e8c36ff45,
-0xb2c5f38436417700,0xf285b3c476013740,
-0x6f1e42335c2d7100,0xc0b1ed9cf382deaf,
-0x7a8ea0542edaf400,0xcd3917e3996d43b7,
-0x7f33175b24684c00,0x3d715519662a0e42,
-0xf7c41221d6e53300,0x8dbe685bac9f497a,
-0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff,
-0x8405f170f4758100,0xd455a120a425d150,
-0xb240a85ae81af200,0x699b738133c129db,
-0xdead5724fa897300,0x592ad0a37d0ef487,
-0x68201c543c744800,0x723a064e266e521a,
-0x219acb7051eabb00,0x9b2071caeb5001ba,
-0x80b75562e2d53700,0x536486b13106e4d3,
-0x6d91f9056894fc00,0x6995fd016c90f804,
-0x5cb17895c924ed00,0x668b42aff31ed73a,
-0x5a4f55451f0a100,0x1abbea4b4eefbe1f,
-0x32bcaa2416988e00,0x73fdeb6557d9cf41,
-0xda3d44a3799ee700,0x43a4dd3ae0077e99,
-0x5898bb7b23e3c000,0x4c8caf6f37f7d414,
-0x76b31edbad68c500,0x9653fe3b4d8825e0,
-0xd064ac18c87cb400,0x52e62e9a4afe3682,
-0x519664a3f235c700,0xa562905706c133f4,
-0x7b64322d56491f00,0x8d92c4dba0bfe9f6,
-0x4f02723f703d4d00,0xcd80f0bdf2bfcf82,
-0xf139cd05f43cc800,0x76be4a8273bb4f87,
-0xecb06539d5895c00,0x5c89d53965b0ec,
-0xa63959c660ff9f00,0x50cfaf30960969f6,
-0x7d1e82e19cff6300,0xd3b02c4f3251cdae,
-0xab28bd3e95168300,0x86059013b83bae2d,
-0x6109f39bfa926800,0x325aa0c8a9c13b53,
-0xf6864a3accbc7000,0xc6b67a0afc8c4030,
-0xa9690bcb62a2c000,0xd61674b41dddbf7f,
-0xe8b25f05edb75a00,0x7c26cb917923ce94,
-0x67e5da583fbd8200,0xcc4e71f3941629ab,
-0xf9d25b7089a22b00,0x6e45cce71e35bc97,
-0x67c341e58226a400,0xe94dcf6b0ca82a8e,
-0xdbae7b0ed5a07500,0x205580f52e5b8efb,
-0x5d8528f8a57dd00,0x24f973aeab76fc21,
-0xac027cd27ed0ae00,0xea0de70dc720ca2,
-0x1c90da564ac68c00,0x911d57dbc74b018d,
-0xc04c5ad6169a8c00,0x1a96800ccc4056da,
-0xfadf2c09f3d62500,0x3411e2c73d18ebce,
-0xcf77e35b942cb800,0xb901952de25ace76,
-0xf46a9806f26c9e00,0x31af5dc337a95bc5,
-0xf0fee9e717190e00,0xb4baada3535d4a44,
-0x845b06d95d82df00,0xf12e73ac28f7aa75,
-0x2b745b042f705f00,0xda85aaf5de81aef1,
-0x2f65561c33794a00,0x713b08426d27145e,
-0x21f25586a774d300,0x33e04794b566c112,
-0xb3d27d1cafce6100,0xe0812e4ffc9d3253,
-0x8e750df67883fb00,0x44bfc73cb24931ca,
-0xe451fc49ad18b500,0x95208d38dc69c471,
-0x51a34dbfee1cf200,0x3f11fedbc4ea052,
-0x7dcaa21568dfb700,0xe0573f88f5422a9d,
-0x67d702b2d565b000,0x5beb3e8ee9598c3c,
-0xb428811da9359c00,0x9804ad318519b02c,
-0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f,
-0x3d00734e734e3d00,0x4d70033e033e4d70,
-0xdf4c22b16efd9300,0xbe2d43d00f9cf261,
-0x36e9419ea877df00,0xb768c01f29f65e81,
-0xd499afe2367b4d00,0xd39ea8e5317c4a07,
-0xcfc9edeb24220600,0x5c5a7e78b7b19593,
-0xc5c3dfd91c1a0600,0x9a9c80864345595f,
-0x9387120695811400,0xdfcb5e4ad9cd584c,
-0xbc469d67db21fa00,0x728853a915ef34ce,
-0x52c555c290079700,0x980f9f085acd5dca,
-0x11fc34d9c825ed00,0xa74a826f7e935bb6,
-0x596d77431a2e3400,0x3f0b11257c485266,
-0x5c7f684b17342300,0x1c3f280b57746340,
-0xfee4b5af514b1a00,0x554f1e04fae0b1ab,
-0x573c7a11462d6b00,0x5932741f4823650e,
-0x624e476b09252c00,0xe222b076549406c,
-0xf58f6e14e19b7a00,0x2258b9c3364cadd7,
-0x24e65a98bc7ec200,0x75b70bc9ed2f9351,
-0xafb4445ff0eb1b00,0x8c97677cd3c83823,
-0xd2277f8a58adf500,0xe81d45b06297cf3a,
-0xdef1b39c426d2f00,0x113e7c538da2e0cf,
-0x99667d821be4ff00,0xce312ad54cb3a857,
-0xc62dfe15d338eb00,0x5eb5668d4ba07398,
-0xfbe60d1de6fb100,0x3e8f51e0ef5e8031,
-0x63d544f29127b600,0x3b52492f147d660,
-0x2ce728e3cf04cb00,0xaf64ab604c874883,
-0xd7549f1ccb488300,0xc142890add5e9516,
-0x21a8d25b7af38900,0xc44d37be9f166ce5,
-0x8bba5e6fe4d53100,0x5c6d89b83302e6d7,
-0xc565df7fba1aa000,0x9f3f8525e040fa5a,
-0x17c457849340d300,0x70a330e3f427b467,
-0xac286eea46c28400,0x6de9af2b870345c1,
-0xf96f29bf46d09600,0xbe286ef80197d147,
-0xf444bb0bff4fb000,0x76c639897dcd3282,
-0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe,
-0x58ca9a0850c29200,0x861444d68e1c4cde,
-0x5e045208560c5a00,0x6832643e603a6c36,
-0xa9aac8cb62610300,0x1a197b78d1d2b0b3,
-0xf87dac29d1548500,0x47c213966eeb3abf,
-0x663ffea7c1985900,0xc89150096f36f7ae,
-0x926e3ec250acfc00,0x897525d94bb7e71b,
-0x208f02ad8d22af00,0x369914bb9b34b916,
-0xefda7a4fa0953500,0x8bbe1e2bc4f15164,
-0x160f435a4c551900,0x3128647d6b723e27,
-0x6ef775ec821b9900,0xcf56d44d23ba38a1,
-0xde0f11c11fced00,0xa74a5bb6bb5647aa,
-0xdb953f71aae44e00,0x82cc6628f3bd1759,
-0xf42b37e81cc3df00,0xd30c10cf3be4f827,
-0x7c51c6eb97ba2d00,0x406dfad7ab86113c,
-0x1c39ffdac6e32500,0x604583a6ba9f597c,
-0x8ef7126be59c7900,0xfb82671e90e90c75,
-0xffafaafa05555000,0xfcaca9f906565303,
-0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc,
-0x9f4aa277e83dd500,0x1fca22f768bd5580,
-0x6b01b6dcb7dd6a00,0x244ef993f892254f,
-0x76f9da5523ac8f00,0xaa250689ff7053dc,
-0x166bf78a9ce17d00,0x7d009ce1f78a166b,
-0x30e6e33505d3d600,0x78aeab7d4d9b9e48,
-0x2a0b24052f0e2100,0xdffed1f0dafbd4f5,
-0xf1bccd8d7c31400,0xc3d700141b0fd8cc,
-0xce0aca0ec004c400,0xe521e125eb2fef2b,
-0xdd97f1bb662c4a00,0x96dcbaf02d67014b,
-0x8756fd2cab7ad100,0xbda71a027f65d8c,
-0x410b206a2b614a00,0xd69cb7fdbcf6dd97,
-0x754acfff8ab5300,0x2f7c84d7d0837b28,
-0xa9b4766bc2df1d00,0xeef3312c85985a47,
-0x49820dc68f44cb00,0x8e45ca0148830cc7,
-0xe97cc752bb2e9500,0x7ce952c72ebb0095,
-0x687d9c89e1f41500,0xd2c726335b4eafba,
-0x73eadc4536af9900,0x3da4920b78e1d74e,
-0xb8ad0a1fa7b21500,0x1005a2b70f1abda8,
-0x44f3fd4a0eb9b700,0xf4434dfabe0907b0,
-0x4e97f42d63bad900,0xa87112cb855c3fe6,
-0x4d7e45763b083300,0x86b58ebdf0c3f8cb,
-0x20b2a03212809200,0xa93b29bb9b091b89,
-0xf3aff6aa59055c00,0x570b520efda1f8a4,
-0xfba60c51aaf75d00,0xb5e8421fe4b9134e,
-0xa3628849ea2bc100,0xa0618b4ae928c203,
-0xd1fc2d00d1fc2d00,0xcee3321fcee3321f,
-0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46,
-0x8647dc1d9b5ac100,0xa465fe3fb978e322,
-0xb9bd84843d39000,0x2dbdfe6e65f5b626,
-0x82ab577efcd52900,0x5a738fa6240df1d8,
-0xb1f9246cdd954800,0x18508dc5743ce1a9,
-0x5697814117d6c00,0xed8190fcf99584e8,
-0x2249e78caec56b00,0x660da3c8ea812f44,
-0x93f0610291f26300,0xe6851477e4871675,
-0x4a84c8064c82ce00,0x65abe72963ade12f,
-0x8670ce38be48f600,0x7f8937c147b10ff9,
-0xbfd2cea31c716d00,0x6e031f72cda0bcd1,
-0x73b75f9be82cc400,0x71b55d99ea2ec602,
-0x7b7ca3a4dfd80700,0x86815e592225fafd,
-0x24ebe6290dc2cf00,0xae616ca38748458a,
-0x243cbba3879f1800,0xb3ab2c3410088f97,
-0xed17fd07ea10fa00,0x33c923d934ce24de,
-0x33b20f8ebd3c8100,0x9e1fa22310912cad,
-0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d,
-0x7768c0dfa8b71f00,0xe7f8504f38278f90,
-0x375bb2dee9856c00,0x2844adc1f69a731f,
-0xaf992f19b6803600,0x93a513258abc0a3c,
-0x7a0f87f288fd7500,0xf1840c790376fe8b,
-0x8015c752d2479500,0xcc598b1e9e0bd94c,
-0x8023be1d9d3ea300,0x48eb76d555f66bc8,
-0x9c2f21920ebdb300,0x15a6a81b87343a89,
-0x30d356b58566e300,0x8e6de80b3bd85dbe,
-0xa9a6222d848b0f00,0xded1555af3fc7877,
-0x89167be46df29f00,0xd74825ba33acc15e,
-0x6b3d2472194f5600,0xe7b1a8fe95c3da8c,
-0x80ce80ce4e004e00,0x501e501e9ed09ed0,
-0x5ac31089d34a9900,0x77ee3da4fe67b42d,
-0x775398bccbef2400,0x2b0fc4e097b3785c,
-0xa7f21742e5b05500,0x5104e1b41346a3f6,
-0xceb2fc8c423e700,0x29ce0aede106c225,
-0x67ffe57d1a829800,0x56ced44c2bb3a931,
-0xb42767f440d39300,0x59ca8a19ad3e7eed,
-0x4f612d034c622e00,0xd3fdb19fd0feb29c,
-0x9750c90e995ec700,0xf433aa6dfa3da463,
-0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4,
-0x931b951d8e068800,0xd850b831098169e,
-0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c,
-0xa3548671d225f700,0x2cdb09fe5daa788f,
-0x1d41184459055c00,0xc29ec79b86da83df,
-0xa7c9d9b7107e6e00,0x76180866c1afbfd1,
-0x6c02f59bf7996e00,0x8ae4137d117f88e6,
-0xb31f2884379bac00,0xcc6057fb48e4d37f,
-0x24dcd62e0af2f800,0x89717b83a75f55ad,
-0xe29fdca1433e7d00,0xe79ad9a4463b7805,
-0x4f75caf0bf853a00,0xcdf748723d07b882,
-0x9ed3d69b05484d00,0x6924216cf2bfbaf7,
-0x4bba837239c8f100,0x4bba837239c8f100,
-0xf0fe2a24d4da0e00,0x353befe1111fcbc5,
-0xa1c3a5c766046200,0xb6d4b2d071137517,
-0x733a94ddaee74900,0xfeb71950236ac48d,
-0x43b2906122d3f100,0x7081a35211e0c233,
-0x7281906311e2f300,0x9c6f7e8dff0c1dee,
-0x681709761e617f00,0x1a657b046c130d72,
-0xa7876040e7c7200,0xc7e7002087a7406,
-0xe747d2729535a000,0x379702a245e570d0,
-0x7ace1ca8d266b400,0xa511c3770db96bdf,
-0x392d697d44501400,0x8c98dcc8f1e5a1b5,
-0x6b74554a213e1f00,0x9a85a4bbd0cfeef1,
-0xd0eb073cecd73b00,0xbd866a5181ba566d,
-0xb44c25dd6991f800,0x1ee68f77c33b52aa,
-0xe65a338f69d5bc00,0x942841fd1ba7ce72,
-0xe32c8f40a36ccf00,0xa966c50ae926854a,
-0x1fa2813c239ebd00,0x84391aa7b805269b,
-0x83ddfca2217f5e00,0xffa180de5d03227c,
-0x486c0521694d2400,0x76523b1f57731a3e,
-0xb37b3af24189c800,0xc20a4b8330f8b971,
-0xd5a0205580f57500,0x2055d5a0750080f5,
-0xebef84806b6f0400,0xeeea81856e6a0105,
-0xef2033fc13dccf00,0xcf0013dc33fcef20,
-0x3f983493ac0ba700,0xac0ba7003f983493,
-0x29483c5d74156100,0xd0b1c5a48dec98f9,
-0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42,
-0xea8a4020caaa600,0x1bbdb11719bfb315,
-0xfd5343ed10beae00,0x832d3d936ec0d07e,
-0xa5a5b3b316160000,0x71716767c2c2d4d4,
-0x4ae8c262288aa00,0x2e84a60c08a2802a,
-0xb5017ace7bcfb400,0xb4007bcf7aceb501,
-0xdddf42429f9d000,0xd2022bfbf6260fdf,
-0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21,
-0x966f847deb12f900,0xf60fe41d8b729960,
-0xeca5ffb65a134900,0xe5acf6bf531a4009,
-0xd286c49042165400,0x72266430e2b6f4a0,
-0xb02146d767f69100,0x62f39405b52443d2,
-0xc563b214d177a600,0xe2449533f6508127,
-0x8d48ae6be623c500,0x509573b63bfe18dd,
-0xdc702d815df1ac00,0xf75b06aa76da872b,
-0x7452b395e1c72600,0x90b657710523c2e4,
-0xfbc34b7388b03800,0xf8c048708bb33b03,
-0x86d8b6e86e305e00,0x732d431d9bc5abf5,
-0x6626014127674000,0xc484a3e385c5e2a2,
-0x37cea0596e97f900,0x6b92fc0532cba55c,
-0x1bbc73d4cf68a700,0xff5897302b8c43e4,
-0x3ca6e27844de9a00,0xf95d14b77eda933,
-0x1da2e25d40ffbf00,0xdc63239c813e7ec1,
-0x3ebcde5c62e08200,0x47c5a7251b99fb79,
-0x6110cbbadbaa7100,0xbbca11600170abda,
-0x53fead0d5ef3a00,0xbe84516b6e5481bb,
-0x5ac17fe4be259b00,0x33a8168dd74cf269,
-0x873ec47dfa43b900,0x62db21981fa65ce5,
-0xad2b4fc964e28600,0xc14723a5088eea6c,
-0xdda5ceb66b137800,0x463e552df088e39b,
-0x5c349ef6aac26800,0x1a72d8b0ec842e46,
-0xca96e3bf75295c00,0x4a16633ff5a9dc80,
-0xb8480cfc44b4f000,0x50a0e414ac5c18e8,
-0xc11072a362b3d100,0xc61775a465b4d607,
-0x97bfa28a1d352800,0xc9e1fcd4436b765e,
-0xf62cd00afc26da00,0x429864be48926eb4,
-0x340cdee6d2ea3800,0x2b13c1f9cdf5271f,
-0x5fc8c156099e9700,0xd84f46d18e191087,
-0x4cf36cd39f20bf00,0x11ae318ec27de25d,
-0xed2f2def02c0c200,0xaf6d6fad40828042,
-0x190da8bca5b11400,0xbfab0e1a0317b2a6,
-0x6d276e2449034a00,0x4309400a672d642e,
-0xb3bda2ac1f110e00,0x323c232d9e908f81,
-0x30e213c1f123d200,0x6cbe4f9dad7f8e5c,
-0x97ec790295ee7b00,0x4d36a3d84f34a1da,
-0x5cebbc0b57e0b700,0x6bdc8b3c60d78037,
-0x30380f07373f0800,0x60685f57676f5850,
-0xdc3dc121fd1ce00,0xe12f30fef33d22ec,
-0xc26ecc6cae02a00,0x3319d3f9f5df153f,
-0xf9d55e728ba72c00,0xc5e9624eb79b103c,
-0x42bdd12e6c93ff00,0xe31c708fcd325ea1,
-0xb594ba9b2e0f2100,0x31103e1faa8ba584,
-0xfd6b3bad50c69600,0xc9aca5ca13767f1,
-0xe3a77034d7934400,0xade93e7a99dd0a4e,
-0x48763709417f3e00,0x3d03427c340a4b75,
-0x2228c8c2e0ea0a00,0x868c6c66444eaea4,
-0x9cfff4970b686300,0x23404b28b4d7dcbf,
-0xdc65ef568a33b900,0xe75ed46db108823b,
-0x3867e7b880df5f00,0x732cacf3cb94144b,
-0x963f7fd640e9a900,0x359cdc75e34a0aa3,
-0x31b58f0b3abe8400,0xdf5b61e5d4506aee,
-0xea316fb45e85db00,0xa8732df61cc79942,
-0xb5b54949fcfc0000,0x747488883d3dc1c1,
-0x43d2910142d3900,0xedd4c0f9fdc4d0e9,
-0xc7894a04c38d4e00,0x1d5390de195794da,
-0xbb19ac0eb517a200,0x1bb90cae15b702a0,
-0x1e2c3d0f11233200,0xc3e2f1d03312012,
-0x7af3e56c169f8900,0xd84921b61e8fe77,
-0xaa72409832ead800,0xfe2614cc66be8c54,
-0xdcdd80815d5c0100,0xf2f3aeaf73722f2e,
-0xd8eae2d20a38300,0xbb38189b961535b6,
-0x5add65e2b83f8700,0x68139bee463db5c,
-0x3b8450efd46bbf00,0xf946922d16a97dc2,
-0x2d903885a815bd00,0x79c46cd1fc41e954,
-0xe3111def0cfef200,0xb3414dbf5caea250,
-0xe19e2e51b0cf7f00,0x778c8b7562999e6,
-0x974cd803944fdb00,0x449f0bd0479c08d3,
-0xd92bf002db29f200,0x6f42fdd04f62ddf,
-0xcb56a538f36e9d00,0x4996af73ca152cf,
-0x26238386a0a50500,0x838626230500a0a5,
-0xb31ea508bb16ad00,0x76db60cd7ed368c5,
-0xf6822e5aacd87400,0x1460ccb84e3a96e2,
-0xa78ae9c4634e2d00,0xe8c5a68b2c01624f,
-0x1dabcf7964d2b600,0xfd4b2f99843256e0,
-0xa315e452f147b600,0x259362d477c13086,
-0x81d27320a1f25300,0x491abbe8693a9bc8,
-0xe7268b4aad6cc100,0x21e04d8c6baa07c6,
-0x5a4e44540e1a100,0x2786c66762c38322,
-0x5d98b6732eebc500,0xe32608cd90557bbe,
-0x91943732a3a60500,0xc4c16267f6f35055,
-0x3e9008a69836ae00,0x5cf26ac4fa54cc62,
-0x1f94d9524dc68b00,0xe9622fa4bb307df6,
-0xedbb1640adfb5600,0x194fe2b4590fa2f4,
-0x1836745a426c2e00,0xfed092bca48ac8e6,
-0xb7110dab1cbaa600,0x5ef8e442f5534fe9,
-0x6347c2e685a12400,0xc8ec694d2e0a8fab,
-0xd6843c6eb8ea5200,0x7c2e96c41240f8aa,
-0x6f41e0cea18f2e00,0x755bfad4bb95341a,
-0x982e2e9800b6b600,0x67d1d167ff4949ff,
-0xc2acd5bb79176e00,0xe688f19f5d334a24,
-0x44aa14fabe50ee00,0x9876c826628c32dc,
-0x34a21482b6209600,0x63f543d5e177c157,
-0x620cb8d6b4da6e00,0x46289cf290fe4a24,
-0xef7d0e9c73e19200,0x9f0d7eec0391e270,
-0x90f17d1c8ced6100,0xb0d15d3caccd4120,
-0xba7cd016ac6ac600,0xe4228e48f234985e,
-0xdb88ce9d46155300,0xa591f4c97c482d1,
-0xccf6734985bf3a00,0x7f45c0fa360c89b3,
-0xa6fee5bd1b435800,0xe4bca7ff59011a42,
-0x3ab029a399138a00,0x41cb52d8e268f17b,
-0x9b924d44dfd60900,0x343de2eb7079a6af,
-0x44ddc9591d84900,0x7039a8e1e5ac3d74,
-0xf3d59fb94a6c2600,0x89afe5c330165c7a,
-0xa5053c9c3999a000,0x4dedd474d17148e8,
-0xef21f43ad51bce00,0xc50bde10ff31e42a,
-0x6263626301000100,0x585958593b3a3b3a,
-0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6,
-0xfe067f877981f800,0x1ae29b639d651ce4,
-0xfb35e22cd719ce00,0xee20f739c20cdb15,
-0xd262da6ab808b000,0x95259d2dff4ff747,
-0x53c031a2f1629300,0xac3fce5d0e9d6cff,
-0x5b7bfede85a52000,0x86a623035878fddd,
-0xf9d43518e1cc2d00,0x8fa2436e97ba5b76,
-0x4edc63f1bf2d9200,0x68fa45d7990bb426,
-0xc964973af35ead00,0x45e81bb67fd2218c,
-0x6f3d21731c4e5200,0x2f7d61335c0e1240,
-0x101df7faeae70d00,0x68658f82929f7578,
-0x24aaa6280c828e00,0xa9272ba5810f038d,
-0xa1b1f8e849591000,0x617138288999d0c0,
-0xe26b4ac321a88900,0x1198b930d25b7af3,
-0x5940160f564f1900,0x372e78613821776e,
-0xdbb2127ba0c96900,0x6a03a3ca1178d8b1,
-0x92639c6dff0ef100,0x72837c8d1fee11e0,
-0xafa2bfb21d100d00,0x878a979a35382528,
-0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6,
-0xa9a28289202b0b00,0x4f44646fc6cdede6,
-0xa4f592c367365100,0x6b3a5d0ca8f99ecf,
-0xe3304c9f7cafd300,0xfd2e528162b1cd1e,
-0xe6ca0529cfe32c00,0xdff33c10f6da1539,
-0xcd403cb17cf18d00,0xc74a36bb76fb870a,
-0xeda64f04e9a24b00,0x92d9307b96dd347f,
-0x86be7941c7ff3800,0xf6ce0931b78f4870,
-0x71a4a87d0cd9d500,0xcb1e12c7b6636fba,
-0x757d848cf9f10800,0x1911e8e0959d646c,
-0xb34652a714e1f500,0x8d786c992adfcb3e,
-0x72bb8f4634fdc900,0x3af3c70e7cb58148,
-0xdff4361dc2e92b00,0xdbf03219c6ed2f04,
-0x17e81ee1f609ff00,0x4db244bbac53a55a,
-0xe3492e8467cdaa00,0xc66c0ba142e88f25,
-0xb062bd6fdf0dd200,0x13c11ecc7cae71a3,
-0xdbb1e68c573d6a00,0x6c06513be08addb7,
-0x754797a5d0e23200,0x586aba88fdcf1f2d,
-0xd5273cce1be9f200,0x83716a984dbfa456,
-0xa522e767c245800,0x277f035b5109752d,
-0xf302c938cb3af100,0xe415de2fdc2de617,
-0x7a61d4cfb5ae1b00,0x869d28334952e7fc,
-0x9b98797ae1e20300,0x5655b4b72c2fcecd,
-0x6601462147206700,0x6a0d4a2d4b2c6b0c,
-0x2e3668705e461800,0x140c524a647c223a,
-0x3223213002131100,0xeafbf9e8dacbc9d8,
-0xf0349e5aaa6ec400,0x9cd67a353973df9,
-0x2d18d2e7caff3500,0x72478db895a06a5f,
-0x9e148a0a941e800,0x31d970989179d038,
-0xac55af56fa03f900,0x38c13bc26e976d94,
-0x3c04a898a49c300,0xdc1f955655961cdf,
-0x71cbc97302b8ba00,0x3b9bb0170cac872,
-0xcecdf6f53b380300,0x7a7942418f8cb7b4,
-0x85d9f7ab2e725c00,0x48143a66e3bf91cd,
-0x7275313644430700,0x90e4a4d3f387c7b,
-0x8e1fef7ef0619100,0x3aab5bca44d525b4,
-0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc,
-0x933bcb63f058a800,0xd27a8a22b119e941,
-0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc,
-0x469033e5a375d600,0xd701a27432e44791,
-0x5237fb9ecca96500,0x1f7ab6d381e4284d,
-0x7e7f3c3d43420100,0x8180c3c2bcbdfeff,
-0x617a233859421b00,0x1c075e45243f667d,
-0x582df085dda87500,0xd1a4790c5421fc89,
-0xce8c3c7eb0f24200,0xf5b707458bc9793b,
-0x79743d3049440d00,0x808dc4c9b0bdf4f9,
-0x787edcdaa2a40600,0x5452f0f68e882a2c,
-0xe427e427c300c300,0x93509350b477b477,
-0xe1ab2d6786cc4a00,0xb9f3753fde941258,
-0x5b63d3ebb0883800,0xad95251d467ecef6,
-0xa6aebfb711190800,0x9b93828a2c24353d,
-0xa84c28cc6480e400,0x42a6c2268e6a0eea,
-0xfd2827f20fdad500,0xa4717eab56838c59,
-0xcb68f7549f3ca300,0x5dfe61c209aa3596,
-0x91fbb8d243296a00,0x9cf6b5df4e24670d,
-0x89da1546cf9c5300,0x7526e9ba3360affc,
-0xe6b22d799fcb5400,0xaafe6135d387184c,
-0xd5587dfd28a5800,0xf6ae7c242971a3fb,
-};
-
-uint64_t i_beta_mul_64_bm4r [2*128*4] __attribute__((aligned(32))) = {
-0xb8b96a6bd3d20100,0x3e3feced55548786,
-0x80a06e4eceee2000,0x4d6da3830323edcd,
-0x8484a3a327270000,0xc1c1e6e662624545,
-0x34bf20ab9f148b00,0xf279e66d59d24dc6,
-0xe0e0cfcf2f2f0000,0x9595baba5a5a7575,
-0xbaf4420cb6f84e00,0x6f2197d9632d9bd5,
-0x9f9f5b5bc4c40000,0x606c2c25d5d9999,
-0xc7a2e48146236500,0x82e7a1c403662045,
-0x606434345450000,0x2e2e6b6b6d6d2828,
-0x5560182d784d3500,0xcbfe86b3e6d3ab9e,
-0x48482e2e66660000,0x6767010149492f2f,
-0x286fd592bafd4700,0xbff842052d6ad097,
-0xc2c23434f6f60000,0x3d3dcbcb0909ffff,
-0xc822d03af218ea00,0x4ca654be769c6e84,
-0x3939d5d5ecec0000,0x66668a8ab3b35f5f,
-0x1b858a140f919e00,0x6ff1fe607be5ea74,
-0xcaca47478d8d0000,0x5c5cd1d11b1b9696,
-0x56ac83792fd5fa00,0x976d42b8ee143bc1,
-0x9f9febeb74740000,0x13136767f8f88c8c,
-0x13dbfd3526eec800,0x5098be7665ad8b43,
-0x65659f9ffafa0000,0x5252a8a8cdcd3737,
-0x96bf8da4321b2900,0x153c0e27b198aa83,
-0xf1f10909f8f80000,0x5656aeae5f5fa7a7,
-0xf4d29bbd496f2600,0x2246d4bbf99d0f6,
-0x3d3d0a0a37370000,0xe7e7d0d0ededdada,
-0x1e4a8bdfc1955400,0xf4a061352b7fbeea,
-0x1e1e565648480000,0x4c4c04041a1a5252,
-0x5fbe36d78869e100,0xf5149c7d22c34baa,
-0x7373efef9c9c0000,0x8f8f13136060fcfc,
-0x1fe840b7a85ff700,0x4f35bacb344ec1b,
-0x6666ddddbbbb0000,0x6969d2d2b4b40f0f,
-0x423fa1dc9ee37d00,0x5e23bdc082ff611c,
-0x7809f687ff8e7100,0xccbd42334b3ac5b4,
-0xa38f96ba19352c00,0x79554c60c3eff6da,
-0x434b2f27646c0800,0xcfc7a3abe8e0848c,
-0x5d0359075a045e00,0x1648124c114f154b,
-0xd1df5e50818f0e00,0x4a44c5cb1a14959b,
-0xacdfcab915667300,0x344752218dfeeb98,
-0xaf3a15802fba9500,0x1a8fa0359a0f20b5,
-0x9531d074e145a400,0x54f011b5208465c1,
-0xbe1813b50bada600,0xa50308ae10b6bd1b,
-0x5fd3d9550a868c00,0xbe3238b4eb676de1,
-0xacd1f58824597d00,0x304d6914b8c5e19c,
-0xfd6903976afe9400,0x72e68c18e5711b8f,
-0x8e6437dd53b9ea00,0xfe5b65cd2386b81,
-0xe52cb970955cc900,0x1fd6438a6fa633fa,
-0x17ad82382f95ba00,0x6cd6f94354eec17b,
-0x30b3cb4878fb8300,0x3ebdc54676f58d0e,
-0xca4b1b9a50d18100,0x1c9dcd4c860757d6,
-0xba8993a3192a300,0xb81b2a89822110b3,
-0xa5ce99f2573c6b00,0xa8c394ff5a31660d,
-0xab2831b2199a8300,0x5fdcc546ed6e77f4,
-0xf607a958ae5ff100,0xc83997669061cf3e,
-0xa531fa6ecb5f9400,0x9b0fc450f561aa3e,
-0x7f39afe996d04600,0x9cda4c0a7533a5e3,
-0x7d1588e09df56800,0x86ee731b660e93fb,
-0x52013f6c3e6d5300,0xaffcc291c390aefd,
-0x488c79bdf531c400,0xdf1bee2a62a65397,
-0xd7a77303d4a47000,0xd2a27606d1a17505,
-0xb7ff7e3681c94800,0x145cdd95226aeba3,
-0x6399c03a59a3fa00,0xd72d748eed174eb4,
-0xd7ceb1a87f661900,0xf1e8978e59403f26,
-0x5f3e98f9a6c76100,0x86e741207f1eb8d9,
-0xcc31af529e63fd00,0x6c910ff23ec35da0,
-0xc16d0fa362ceac00,0x16bad874b5197bd7,
-0xbfab998d32261400,0xf1b293d8296a4b0,
-0xc2f02113d1e33200,0xdbe9380ac8fa2b19,
-0x5d04fba2ffa65900,0x154cb3eab7ee1148,
-0xdff8c5e23d1a2700,0x3c1b2601def9c4e3,
-0xbda7e2f8455f1a00,0x455f1a00bda7e2f8,
-0xe632ca1ef82cd400,0x29fd05d137e31bcf,
-0xe916b04fa659ff00,0x7c8325da33cc6a95,
-0xf4a6ce9c683a5200,0x2270184abeec84d6,
-0xc0b896ee2e567800,0x572f0179b9c1ef97,
-0x2bb962f2d94b900,0x5ce5c87173cae75e,
-0xee7055cb25bb9e00,0x5ec0e57b950b2eb0,
-0xee0a64846a8ee00,0x638dcb252bc5836d,
-0x2a483c5e74166200,0x593b4f2d07651173,
-0x49d02eb7fe679900,0x69f00e97de47b920,
-0x9d978c861b110a00,0x8f859e9409031812,
-0xe6a1b3f412554700,0xabecfeb95f180a4d,
-0x37012f192e183600,0x6157794f784e6056,
-0x286eca8ca4e24600,0x4600a4e2ca8c286e,
-0xca68f2509a38a200,0x8e2cb614de7ce644,
-0x5db2ee015cb3ef00,0xbc530fe0bd520ee1,
-0xf92f00d62ff9d600,0x15c3ec3ac3153aec,
-0xb25147a416f5e300,0xf41701e250b3a546,
-0x9dbd22029fbf2000,0xad8d1232af8f1030,
-0x4ce911b4f85da500,0x3f9a62c78b2ed673,
-0xf9ca6556af9c3300,0xc6f55a6990a30c3f,
-0x4e9865b3fd2bd600,0xc412ef3977a15c8a,
-0x4677625315243100,0xf0c1d4e5a39287b6,
-0x2e601d537d334e00,0x86c8b5fbd59be6a8,
-0x44c455d591118000,0x890998185cdc4dcd,
-0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4,
-0x2167561031774600,0x442733514526325,
-0xe0d8073fdfe73800,0x6f5788b05068b78f,
-0xe3219052b173c200,0xcd0fbe7c9f5dec2e,
-0xf6b5c3837536400,0x593d0a6e61053256,
-0xd34abc25f66f9900,0x6bf2049d4ed721b8,
-0x8b55ad73f826de00,0x75ab538d06d820fe,
-0x4766d9f8bf9e2100,0xe9c8775611308fae,
-0x3cfce2221edec000,0xa66678b884445a9a,
-0xfc51913cc06dad00,0x4de0208d71dc1cb1,
-0x876524c641a3e200,0xdf3d7c9e19fbba58,
-0x4a8a985812d2c000,0x13d3c1014b8b9959,
-0x5288449ecc16da00,0x23f935efbd67ab71,
-0x4237126725507500,0x9eebcebbf98ca9dc,
-0x3fe6954c73aad900,0x4f96e53c03daa970,
-0x47cfc64e09818800,0x24aca52d6ae2eb63,
-0xb98b4476cffd3200,0xb587487ac3f13e0c,
-0xe7b90e5eb9e7500,0xccb95227295cb7c2,
-0xf371078576f48200,0xe8cfa788b097ffd,
-0xa719912f8836be00,0x843ab20cab159d23,
-0x89c5115dd4984c00,0xb5f92d61e8a4703c,
-0x50cce47828b49c00,0xd44860fcac301884,
-0xa1b1869637271000,0xefffc8d879695e4e,
-0x1f3b391d02262400,0x4c686a4e51757753,
-0x3237fbfeccc90500,0xbcb9757042478b8e,
-0x6077d7c7a7b0100,0x2d2c565751502a2b,
-0x2e268f87a9a10800,0xfff75e567870d9d1,
-0x73212e7c0f5d5200,0x72202f7d0e5c5301,
-0x458d38f0b57dc800,0x9951e42c69a114dc,
-0x7b0bc7b7ccbc7000,0x373bfcfb4c40878,
-0x4b148fdf94cb500,0x299c65d0d461982d,
-0xd591145481c5400,0xfbafe7b3beeaa2f6,
-0xc32aa34a8960e900,0xc32aa34a8960e900,
-0x235ab6cfec957900,0x4b32dea784fd1168,
-0x3eff71b08e4fc100,0xe524aa6b55941adb,
-0x476184a2e5c32600,0x99bf5a7c3b1df8de,
-0x63f89a0162f99b00,0x7ce7851e7de6841f,
-0x4eba1de9a753f400,0x29dd7a8ec0349367,
-0xe25fa914f64bbd00,0xec51a71af845b30e,
-0x52f72386d471a500,0x52f72386d471a500,
-0xf9c4023fc6fb3d00,0xa994526f96ab6d50,
-0x925b25ec7eb7c900,0xea235d9406cfb178,
-0xbf963e17a8812900,0x755cf4dd624be3ca,
-0xe1b1baea0b5b5000,0x45151e4eaffff4a4,
-0xaee791d8763f4900,0xa2eb9dd47a33450c,
-0x17a511a3b406b200,0x17a511a3b406b200,
-0x2e6a9edaf4b04400,0xd59165210f4bbffb,
-0x87972e3eb9a91000,0x3a2a93830414adbd,
-0xe1bea0ff1e415f00,0xe4bba5fa1b445a05,
-0x689a7d8fe715f200,0x11e304f69e6c8b79,
-0xe30eb558bb56ed00,0x43ae15f81bf64da0,
-0x5ddffa7825a78200,0xf67451d38e0c29ab,
-0x9b96dad74c410d00,0xd004c41dad79b96,
-0xf0965432c2a46600,0x4e28ea8c7c1ad8be,
-0xfcb5b1f8044d4900,0x95dcd8916d242069,
-0x5d24ef96cbb27900,0xa8d11a633e478cf5,
-0xfae6839f65791c00,0x504c2935cfd3b6aa,
-0xab0ef257fc59a500,0x4aef13b61db844e1,
-0x12bd3f90822daf00,0xe946c46b79d654fb,
-0x4dbe23d39e6df00,0xf62910cfcb142df2,
-0xe3abb8f81b53400,0x6d59d8ece2d65763,
-0xeaf6f9e50f131c00,0x839f908c667a7569,
-0xe171f06081119000,0x4ada5bcb2aba3bab,
-0x9d95838b161e0800,0x848c9a920f071119,
-0xbc5e24c67a98e200,0xd4364cae12f08a68,
-0x2e7833654b1d5600,0x30662d7b5503481e,
-0x4e20e48ac4aa6e00,0xc2ac68064826e28c,
-0x91a40633a2973500,0xecd97b4edfea487d,
-0xe8e76b648c830f00,0xeee16d628a850906,
-0x462894fabcd26e00,0x8ce25e307618a4ca,
-0x5eddd0530d8e8300,0x82010c8fd1525fdc,
-0xbbba5e5fe4e50100,0xb0b15554efee0a0b,
-0xff4363df209cbc00,0xbb7972bd46848f4,
-0xe76235b057d28500,0x46c39411f67324a1,
-0xfcd589a9557c200,0x589a0fcdc2009557,
-0xda40cb518b119a00,0x4fd55ec41e840f95,
-0xeb7d17816afc9600,0xd84e24b259cfa533,
-0x86945e4ccad81200,0x1705cfdd5b498391,
-0x496093baf3da2900,0x674ebd94ddf4072e,
-0x43f8259edd66bb00,0x76cd10abe8538e35,
-0x82d6194dcf9b5400,0x5c08c79311458ade,
-0x2969195970304000,0xedaddd9db4f484c4,
-0xf9e1e0f801191800,0xa9b1b0a851494850,
-0x6177b6a6c7d1100,0xeffe92838594f8e9,
-0x6bf9a93b50c29200,0x8c1e4edcb72575e7,
-0x7ed997304ee9a700,0x3b9cd2750bace245,
-0x58bf1bfca443e700,0x9f78dc3b638420c7,
-0x13ea34cdde27f900,0xfd04da2330c917ee,
-0xd2eba39a48713900,0xa198d0e93b024a73,
-0xd3a284f526577100,0xb0c1e79645341263,
-0x891e05921b8c9700,0x83140f9811869d0a,
-0x1fa33c809f23bc00,0xb30f902c338f10ac,
-0x2542cbac89ee6700,0x166ef88adca4324,
-0x15342b0a1f3e2100,0x86a7b8998cadb293,
-0x32d05bb98b69e200,0xfc1e957745a72cce,
-0xed3ffc2ec311d200,0x2bf93ae805d714c6,
-0x5b3f64643f5b00,0xf2a9cd9696cda9f2,
-0xb18885bc0d343900,0x774e437acbf2ffc6,
-0x886258b23ad0ea00,0x1ebd13bb3596389,
-0x2d15b888a59d300,0x13c04a999b48c211,
-0x28759fc2eab75d00,0xda876d301845aff2,
-0x88a8301098b82000,0x2c0c94b43c1c84a4,
-0xa029008929a08900,0x73fad35afa735ad3,
-0x6230ebb9db895200,0xa5f72c7e1c4e95c7,
-0x4a76407c360a3c00,0xba86b08cc6faccf0,
-0xf9d2ddf60f242b00,0xfad1def50c272803,
-0x4d4fd2d29f9d000,0xcdcf52521f1d808,
-0x82777c890bfef500,0x13e6ed189a6f6491,
-0x135be8a0b3fb4800,0x99d1622a3971c28a,
-0x35268a99acbf1300,0x5d4ee2f1c4d77b68,
-0x881b74e76ffc9300,0x8f1c73e068fb9407,
-0xb6acecf6405a1a00,0xf4eeaeb402185842,
-0x1ad0559f854fca00,0x864cc90319d3569c,
-0x632dc48ae9a74e00,0x9bd53c72115fb6f8,
-0x7a1f41245e3b6500,0x9affa1c4bedb85e0,
-0x11aa0db6a71cbb00,0x2893348f9e258239,
-0x2defad6f4280c200,0xc90b498ba66426e4,
-0x5e51fdf2aca30f00,0x6768c4cb959a3639,
-0xded84b4d93950600,0x2721b2b46a6cfff9,
-0xad54c33a976ef900,0x1ce5728b26df48b1,
-0xb6f1d99e286f4700,0x82c5edaa1c5b7334,
-0x3681cb7c4afdb700,0x3285cf784ef9b304,
-0x9f3e51f06fcea100,0xa1006fce51f09f3e,
-0x9288a2b82a301a00,0x415b716bf9e3c9d3,
-0x7b072458235f7c00,0x770b28542f53700c,
-0xd7da6e63b4b90d00,0x808d3934e3ee5a57,
-0x2b9b40f0db6bb00,0xb40f02b9bb000db6,
-0x32264b5f6d791400,0x1d09647042563b2f,
-0x8803cb4bc348800,0x2ba31f979f17ab23,
-0x58ea49fba311b200,0xa91bb80a52e043f1,
-0x6d0e4a2944276300,0x563571127f1c583b,
-0x5a2e24540e7a700,0x2b8ccc6b6ec9892e,
-0x9749fe2eb967d00,0x3e43a8d5dca14a37,
-0x42f53780c275b700,0x18af6dda982fed5a,
-0xef2dea28c705c200,0xa86aad6f80428547,
-0x884007cf478fc800,0x2ae2a56de52d6aa2,
-0x959915198c800c00,0xbbb73b37a2ae222e,
-0xf0209343b363d000,0xada69b949992afa,
-0x5e9e90500ecec00,0xe90505e9ec0000ec,
-0x9da5350d90a83800,0x774fdfe77a42d2ea,
-0xf45f8328dc77ab00,0x2c875bf004af73d8,
-0x40dd5ac7871a9d00,0x920f881555c84fd2,
-0x35e7855762b0d200,0xcc1e7cae9b492bf9,
-0xd41beb24f03fcf00,0xae61915e8a45b57a,
-0x424ce5eba9a70e00,0xb3bd141a5856fff1,
-0xa24630d47692e400,0xf612648022c6b054,
-0xb0698c55e53cd900,0x3fe603da6ab3568f,
-0x2178376e4f165900,0xe7bef1a889d09fc6,
-0xb141a959e818f000,0xb848a050e111f909,
-0x5d951cd48941c800,0xd81099510cc44d85,
-0xa21d7dc260dfbf00,0x69d6b609ab1474cb,
-0x23ba3ea7841d9900,0xac35b1280b92168f,
-0x56e9912e78c7bf00,0xeb1c976209fe758,
-0xc60ce228ee24ca00,0xe329c70dcb01ef25,
-0xef8a2d48a7c26500,0x97f25530dfba1d78,
-0x46ab18f5b35eed00,0xa64bf81553be0de0,
-0xe67f54cd2bb29900,0x930a21b85ec7ec75,
-0xf01cde32c22eec00,0x40ac6e82729e5cb0,
-0xd612cb0fd91dc400,0xdb1fc602d410c90d,
-0x885f69be36e1d700,0xaf784e9911c6f027,
-0xa1b05544e5f41100,0x6b7a9f8e2f3edbca,
-0x3e126448765a2c00,0x8ba7d1fdc3ef99b5,
-0x24d033c7e317f400,0x20d437c3e713f004,
-0x39dad83b02e1e300,0x618280635ab9bb58,
-0x79b4e12c5598cd00,0x74b9ec215895c00d,
-0x35ddeb0336dee800,0xc62e18f0c52d1bf3,
-0x6da45a93fe37c900,0x76bf4188e52cd21b,
-0x7f0438433c477b00,0xa714d3649320e75,
-0x6c85ee076b82e900,0x29c0ab422ec7ac45,
-0x977da74dda30ea00,0x3fd50fe5729842a8,
-0x7bcb08b8c373b000,0x6ddd1eaed565a616,
-0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440,
-0x3cea5a8cb066d600,0xe73181576bbd0ddb,
-0x23c5f61033d5e600,0xaf497a9cbf596a8c,
-0xd10ed40bda05df00,0xc21dc718c916cc13,
-0x3922cad1e8f31b00,0x2239d1caf3e8001b,
-0x71a2835322f1d00,0xa3be8c91968bb9a4,
-0x7907403e47397e00,0xd0aee997ee90d7a9,
-0x4ebb1beea055f500,0xc03595602edb7b8e,
-0xcbfbaa9a51613000,0xae9ecfff34045565,
-0x6e970ff69861f900,0xe41d857c12eb738a,
-0x94dbaae5713e4f00,0x216e1f50c48bfab5,
-0x2ad4be406a94fe00,0xbb452fd1fb056f91,
-0x84c7783bbffc4300,0x4003bcff7b3887c4,
-0x508969b9e930d00,0x505dc3cecbc65855,
-0xe85a4ffd15a7b200,0xbf0d18aa42f0e557,
-0x16739df8ee8b6500,0xa8cd23465035dbbe,
-0x175594d6c1834200,0x6f2decaeb9fb3a78,
-0xee901f618ff17e00,0x5b25aad43a44cbb5,
-0x98a65c62fac43e00,0x221ce6d8407e84ba,
-0x10f32ac9d93ae300,0x4e73eddcd2ef714,
-0xd31123e132f0c200,0x69ab995b884a78ba,
-0x695daa9ef7c33400,0xb28671452c18efdb,
-0xffb5cf857a304a00,0xeea4de946b215b11,
-0x6ba2ae670cc5c900,0x34fdf138539a965f,
-0x34a18e1b2fba9500,0x42d7f86d59cce376,
-0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171,
-0xa4d61b69cdbf7200,0x7d0fc2b01466abd9,
-0x83b92d1794ae3a00,0x9ea4300a89b3271d,
-0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc,
-0xf672fe7a8c088400,0x5ade52d620a428ac,
-0xc7785fe02798bf00,0x229dba05c27d5ae5,
-0xbccbadda66117700,0x33442255e99ef88f,
-0xec23d817fb34cf00,0xb9768d42ae619a55,
-0xf0095aa353aaf900,0x20d98a73837a29d0,
-0xb25329c87a9be100,0x7190ea0bb95822c3,
-0x5a963ff3a965cc00,0x7cb62aef438915d,
-0xe6d57d4ea89b3300,0x15268ebd5b68c0f3,
-0xe4c02404e0c4200,0x67256b2927652b69,
-0x9ef81177e98f6600,0xa2c42d4bd5b35a3c,
-0xfd08aa5fa257f500,0x9065c732cf3a986d,
-0xce604be52b85ae00,0xd17f54fa349ab11f,
-0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf,
-0x9b4a66b72cfdd100,0x3cedc1108b5a76a7,
-0x98ab5261f9ca3300,0xdfec1526be8d7447,
-0x2ce1bf725e93cd00,0xd71a4489a56836fb,
-0xb6adb4af19021b00,0xc5dec7dc6a716873,
-0xa960935af33ac900,0x6ea7549d34fd0ec7,
-0xe2a57e39db9c4700,0x8ccb1057b5f2296e,
-0x357a9ad5e0af4f00,0x1956b6f9cc83632c,
-0x2583832500a6a600,0xd37575d3f65050f6,
-0x6d646f660b020900,0xa6afa4adc0c9c2cb,
-0x8135c672f347b400,0xb105f642c3778430,
-0x4916c29dd48b5f00,0x5a05d18ec7984c13,
-0xa45cfb03a75ff800,0x52aa0df551a90ef6,
-0xcfefdafa35152000,0x14340121eecefbdb,
-0x21628fccedae4300,0x682bc685a4e70a49,
-0x97a399ad3a0e3400,0xdaeed4e07743794d,
-0x3147f385b4c27600,0xd4a21660512793e5,
-0xf86d45d028bd9500,0x93062ebb43d6fe6b,
-0xa8f392c9613a5b00,0xb8e382d9712a4b10,
-0x7cf854d0ac288400,0xb135991d61e549cd,
-0x95b8ad8015382d00,0xfed3c6eb7e53466b,
-0xac9f88bb17243300,0xbc8f98ab07342310,
-0xe30920ca29c3ea00,0xec062fc526cce50f,
-0xf3d1f5d724062200,0x33113517e4c6e2c0,
-0xc5ab523cf9976e00,0x9af40d63a6c8315f,
-0x3c5c84e4d8b86000,0x3e5e86e6daba6202,
-0xe0207cbc5c9cc000,0xe92975b55595c909,
-0xc3a5355390f66600,0xf89e0e68abcd5d3b,
-0x92ab5168fac33900,0x3b02f8c1536a90a9,
-0xb7014cfa4dfbb600,0x15a3ee58ef5914a2,
-0xce7c2a9856e4b200,0x7bc99f2de35107b5,
-0xf006e711e117f600,0x996f8e78887e9f69,
-0x520b94cd9fc65900,0xcd940b520059c69f,
-0x534ca7b8ebf41f00,0x78678c93c0df342b,
-0x7d668b90edf61b00,0x776c819ae7fc110a,
-0xf2dfcde0123f2d00,0x210c1e33c1ecfed3,
-0xfe0a5fab55a1f400,0x6c98cd39c7336692,
-0xb8b26c66ded40a00,0x707aa4ae161cc2c8,
-0xcfde0e1fd0c11100,0xe5f42435faeb3b2a,
-0xa9947b46efd23d00,0x211cf3ce675ab588,
-0xd96be95b8230b200,0xb80a883ae351d361,
-0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce,
-0x9cef790a96e57300,0xd4a73142dead3b48,
-0x9f065ec758c19900,0xd24b138a158cd44d,
-0xfe8d2457a9da7300,0xe291384bb5c66f1c,
-0xd5ef0e34e1db3a00,0x251ffec4112bcaf0,
-0xf268ab31c3599a00,0xab31f2689a00c359,
-0xe17f76e809979e00,0xb72920be5fc1c856,
-0x3f76f9b08fc64900,0xfdb43b724d048bc2,
-0x31289c85b4ad1900,0xa8b1051c2d348099,
-0xa75e3bc2659cf900,0x6e97f20bac5530c9,
-0x222c414f6d630e00,0x6b650806242a4749,
-0x52deb23e6ce08c00,0x800c60ecbe325ed2,
-0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab,
-0x8bb589b73c023e00,0x19271b25ae90ac92,
-0x764a9cacdae6300,0x566abc8cfac6102,
-0x81bdab97162a3c00,0x201c0a36b78b9da1,
-0x8a3d992ea413b700,0x6add79ce44f357e0,
-0xbab43c3288860e00,0xfaf47c72c8c64e40,
-0x33917edcef4da200,0x1ebc53f1c2608f2d,
-0x29efdc1a33f5c600,0x4482b1775e98ab6d,
-0xe17e0e9170ef9f00,0x3da2d24dac3343dc,
-0x97f61879ee8f6100,0x7e1ff190076688e9,
-0x4040040444440000,0xf3f3b7b7f7f7b3b3,
-0xa8a7333c949b0f00,0x1817838c242bbfb0,
-0x50a34dbeee1df300,0x2cdf31c292618f7c,
-0xaebb2c3997821500,0x4055c2d7796cfbee,
-0x1743d48493c7500,0x97e2abdedfaae396,
-0x9b983033a8ab0300,0x8a892122b9ba1211,
-0x442b026d29466f00,0x4629006f2b446d02,
-0x2d96d06b46fdbb00,0x8c3771cae75c1aa1,
-0x765d466d1b302b00,0x84afb49fe9c2d9f2,
-0xecf94555b9ac100,0x80411adbd5144f8e,
-0xbb354ece75fb800,0x348c6bd3d860873f,
-0xec67840fe3688b00,0xf972911af67d9e15,
-0x611f522c4d337e00,0x84fab7c9a8d69be5,
-0xf55079dc298ca500,0x49ecc560953019bc,
-0xe35845fe1da6bb00,0x10abb60dee5548f3,
-0xa7bbffe344581c00,0xd2ce8a96312d6975,
-0x1ca004b8a418bc00,0xbf03a71b07bb1fa3,
-0x7e66948cf2ea1800,0x948c7e661800f2ea,
-0x224ca2ccee806e00,0x355bb5dbf9977917,
-0x4c52405e120c1e00,0xb1afbda3eff1e3fd,
-0x80ec563abad66c00,0xb8d46e0282ee5438,
-0xeeb3d588663b5d00,0x64395f02ecb1d78a,
-0x53dfb73b68e48c00,0x64e8800c5fd3bb37,
-0xfc5059f509a5ac00,0x3a969f33cf636ac6,
-0xcbd02932f9e21b00,0x51ee7fc372cd5ce,
-0x5ba640bde61bfd00,0x9a67817c27da3cc1,
-0x565d8d86d0db0b00,0x565d8d86d0db0b00,
-0x8696afbf39291000,0x4f5f6676f0e0d9c9,
-0x916fc33dac52fe00,0xe51bb749d8268a74,
-0x92d47a3caee84600,0xda9c3274e6a00e48,
-0x26e9549bbd72cf00,0x1ed16ca3854af738,
-0x11a408bdac19b500,0x6bde72c7d663cf7a,
-0x3b612f754e145a00,0x9fc58bd1eab0fea4,
-0xf6ff8d84727b0900,0x373e4c45b3bac8c1,
-0xa7339307a0349400,0x31a5059136a20296,
-0x601d7d00601d7d00,0x4f32522f4f32522f,
-0xb9d1593188e06800,0x5830b8d0690189e1,
-0x9c7319f66a85ef00,0x937c16f9658ae00f,
-0xb769ca14a37dde00,0x27f95a8433ed4e90,
-0xc32134d615f7e200,0x9674618340a2b755,
-0x4e6c6a4806242200,0x391b1d3f71535577,
-0x68312f761e475900,0xb9e0fea7cf9688d1,
-0xd30571a774a2d600,0x9c4a3ee83bed994f,
-0x8990dfc64f561900,0x7e672831b8a1eef7,
-0x2023a2a181820300,0xbfbc3d3e1e1d9c9f,
-0xe26956dd3fb48b00,0xac27189371fac54e,
-0xd95f2ea871f78600,0x66e09117ce4839bf,
-0x32cb27deec15f900,0xaa53bf46748d6198,
-0xcdb3e39d502e7e00,0xe896c6b8750b5b25,
-0xc999bded24745000,0x21715505cc9cb8e8,
-0x280c6b4f67432400,0x795d3a1e36127551,
-0xd0ca859f4f551a00,0xf155a40908ac5df,
-0x5167d6e0b1873600,0x94a213257442f3c5,
-0x43defd6d2eb3900,0xe0d90b32360fdde4,
-0x417f98a6e7d93e00,0x13fd8e6a7997e40,
-0x34e96eb3875add00,0x20fd7aa7934ec914,
-0xaaa2464ee4ec0800,0x535bbfb71d15f1f9,
-0xf2a07725d7855200,0x7022f5a75507d082,
-0x89b34b71f8c23a00,0x7e44bc860f35cdf7,
-0x47b6e11057a6f100,0xe71641b0f70651a0,
-0x1bc7fe2239e5dc00,0xb76b528e954970ac,
-0x5488db07538fdc00,0xe23e6db1e5396ab6,
-0xf22c588674aade00,0xd80672ac5e80f42a,
-0x159d76feeb638800,0x1d957ef6e36b8008,
-0xebebc3c328280000,0x24240c0ce7e7cfcf,
-0x95ba022db8972f00,0x3f10a887123d85aa,
-0x4a53554c061f1900,0xd3caccd59f868099,
-0xebd3f6ce251d3800,0xb189ac947f47625a,
-0x7db9e92d5094c400,0xc1055591ec2878bc,
-0x6ac00aaac06aa00,0x4de74be1e74de14b,
-0x37669fcef9a85100,0xd4857c2d1a4bb2e3,
-0xd618c00ed816ce00,0x3af42ce234fa22ec,
-0x22cd739cbe51ef00,0x9a75cb2406e957b8,
-0xa2b64652f0e41400,0x617585913327d7c3,
-0x3c0de1d1eddc300,0xb47769aaa96a74b7,
-0xaa771dcd67bad00,0x2c8157faf05d8b26,
-0x870aa429ae238d00,0x61ec42cf48c56be6,
-0x5ae3b90953eab00,0xca61f45f5af164cf,
-0xbc215bc67ae79d00,0xf16c168b37aad04d,
-0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2,
-0xde2ac430ee1af400,0x2f618ec32c628dc,
-0x3a0b8bba80b13100,0xf4c545744e7fffce,
-0x2cdb1cebc730f700,0x9265a255798e49be,
-0x56141d5f094b4200,0xf6b4bdffa9ebe2a0,
-0xb7ac455ee9f21b00,0xe7fc150eb9a24b50,
-0x968ad8c4524e1c00,0x21e4c50c6da8894,
-0x1ddacc0b16d1c700,0x2cebfd3a27e0f631,
-0x28539be0c8b37b00,0x99e22a517902cab1,
-0xc38281c003424100,0x91d0d39251101352,
-0x8681beb93f380700,0xbeb9868107003f38,
-0xefd77b43ac943800,0x122a86be5169c5fd,
-0x9ec67e26b8e05800,0x366ed68e1048f0a8,
-0x875fed35b26ad800,0x71a91bc3449c2ef6,
-0x2bc23ad3f811e900,0x78916980ab42ba53,
-0x2211417250633300,0xf0c393a082b1e1d2,
-0x4cd01b87cb579c00,0xc458930f43df1488,
-0x7405651460117100,0xfd8cec9de998f889,
-0xf812d832ca20ea00,0x816ba14bb3599379,
-0xdf7c53f02f8ca300,0xf55679da05a6892a,
-0x16685e2036487e00,0x57b4d33255b6d13,
-0x4d24e78ec3aa6900,0x69aac38ee7244d,
-0xf4853c4db9c87100,0x413089f80c7dc4b5,
-0x237a451c3f665900,0xecb58ad3f0a996cf,
-0x5206b4e4b6e2500,0x83a6edc8cde8a386,
-0x434358581b1b0000,0xacacb7b7f4f4efef,
-0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc,
-0x5825a7da82ff7d00,0x88f5770a522fadd0,
-0x26fb7da0865bdd00,0x7ea325f8de038558,
-0x133c002f3c132f00,0xecc3ffd0c3ecd0ff,
-0x8aa97556dcff2300,0xb695496ae0c31f3c,
-0x7d067b0b760d700,0x7aad1acdca1daa7d,
-0x6966303f56590f00,0xefe0b6b9d0df8986,
-0x1d93850b16988e00,0x38d9b150886901e,
-0x6b48b497fcdf2300,0x81a25e7d1635c9ea,
-0x40094a03430a4900,0xde97d49ddd94d79e,
-0x74019aef9bee7500,0x4b3ea5d0a4d14a3f,
-0x36691c43752a5f00,0x2f70055a6c334619,
-0xbba91507bcae1200,0xcfdd6173c8da6674,
-0x2980993910b9a00,0xa90019b99039208,
-0xfc3bb0778b4cc700,0xac6be027db1c9750,
-0x70ed1f82f26f9d00,0x118c7ee3930efc61,
-0x8c5ac7119d4bd600,0xeb3da076fa2cb167,
-0x8a18fe6ce6749200,0x9a08ee7cf6648210,
-0xfa5b48e913b2a100,0x75d4c7669c3d2e8f,
-0x6d660d066b600b00,0xd066d660b006b60,
-0xc5c16763a6a20400,0xa8ac0a0ecbcf696d,
-0x1b48f2a1bae95300,0x4112a8fbe0b3095a,
-0xb0c3e49727547300,0xc5b691e252210675,
-0x420cc789cb854e00,0x622ce7a9eba56e20,
-0x4d3abbcc81f67700,0x5225a4d39ee9681f,
-0x5192e32071b2c300,0xbe7d0ccf9e5d2cef,
-0x3b7482cdf6b94f00,0xca85733c0748bef1,
-0xfb451ca259e7be00,0xb00e57e912acf54b,
-0x8f1ee372fd6c9100,0x9809f465ea7b8617,
-0x7784956611e2f300,0xa85b4ab9ce3d2cdf,
-0xc0de5e4e8e90100,0xa0be3e2eeef0706,
-0xe92b8644ad6fc200,0x5a9835f71edc71b3,
-0x67256b294e0c4200,0xda98d694f3b1ffbd,
-0xc7dd4a5a9d87100,0xd3a20b7a7607aedf,
-0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620,
-0x2b73fba388d05800,0xc79f174f643cb4ec,
-0xbe91022d93bc2f00,0xa38c1f308ea1321d,
-0x79e622bdc45b9f00,0xb926e27d049b5fc0,
-};
-
-
-uint64_t beta_mul_64_bm4r_ext_8 [2*128*4*2] __attribute__((aligned(32))) = {
-0x8d8cadac21200100,0x9c9dbcbd30311011,0x8d8cadac21200100,0x9c9dbcbd30311011,
-0xfe769810ee668800,0x8008e66e9018f67e,0xfe769810ee668800,0x8008e66e9018f67e,
-0xb2b25454e6e60000,0xa2a24444f6f61010,0xb2b25454e6e60000,0xa2a24444f6f61010,
-0xbf50cf209f70ef00,0xdc33ac43fc138c63,0xbf50cf209f70ef00,0xdc33ac43fc138c63,
-0xe3e3707093930000,0xc7c75454b7b72424,0xe3e3707093930000,0xc7c75454b7b72424,
-0xc5f4a8995c6d3100,0xaa9bc7f633025e6f,0xc5f4a8995c6d3100,0xaa9bc7f633025e6f,
-0xc7c7d7d710100000,0x3c3c2c2cebebfbfb,0xc7c7d7d710100000,0x3c3c2c2cebebfbfb,
-0x5f51ddd38c820e00,0xf0fe727c232da1af,0x5f51ddd38c820e00,0xf0fe727c232da1af,
-0x8080949414140000,0x8181959515150101,0x8080949414140000,0x8181959515150101,
-0x4de4d37a379ea900,0x57fec9602d84b31a,0x4de4d37a379ea900,0x57fec9602d84b31a,
-0x5d5d141449490000,0xa3a3eaeab7b7fefe,0x5d5d141449490000,0xa3a3eaeab7b7fefe,
-0xd357119546c28400,0xe8acc489b1f59dd,0xd357119546c28400,0xe8acc489b1f59dd,
-0xe9e91a1af3f30000,0x303f0f01919eaea,0xe9e91a1af3f30000,0x303f0f01919eaea,
-0xf0646bff0f9b9400,0xdc4847d323b7b82c,0xf0646bff0f9b9400,0xdc4847d323b7b82c,
-0x5050777727270000,0x5d5d7a7a2a2a0d0d,0x5050777727270000,0x5d5d7a7a2a2a0d0d,
-0x7e5aeecab4902400,0xffdb6f4b3511a581,0x7e5aeecab4902400,0xffdb6f4b3511a581,
-0xede1333fd2de0c00,0xa6aa78749995474b,0xede1333fd2de0c00,0xa6aa78749995474b,
-0x7688be4036c8fe00,0xe41a2cd2a45a6c92,0x7688be4036c8fe00,0xe41a2cd2a45a6c92,
-0x7a583a1862402200,0x1b395b7903214361,0x7a583a1862402200,0x1b395b7903214361,
-0xea90a7dd374d7a00,0x6b11265cb6ccfb81,0xea90a7dd374d7a00,0x6b11265cb6ccfb81,
-0x5273d9f8aa8b2100,0xfbda7051032288a9,0x5273d9f8aa8b2100,0xfbda7051032288a9,
-0xf534d819ec2dc100,0x46876baa5f9e72b3,0xf534d819ec2dc100,0x46876baa5f9e72b3,
-0xd4c3c3d400171700,0xd0c7c7d004131304,0xd4c3c3d400171700,0xd0c7c7d004131304,
-0xf9d6230cf5da2f00,0x827d2fd042bdef1,0xf9d6230cf5da2f00,0x827d2fd042bdef1,
-0x4ca91cf9b550e500,0x39dc698cc0259075,0x4ca91cf9b550e500,0x39dc698cc0259075,
-0xc2a57710d2b56700,0x661b3d41671a3c4,0xc2a57710d2b56700,0x661b3d41671a3c4,
-0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81,0x515dbbb7e6ea0c00,0xd0dc3a36676b8d81,
-0x7bf68c017af78d00,0x489f37e0588f27f,0x7bf68c017af78d00,0x489f37e0588f27f,
-0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a,0x1262b4c4d6a67000,0x4838ee9e8cfc2a5a,
-0xbf58709728cfe700,0x1ef9d136896e46a1,0xbf58709728cfe700,0x1ef9d136896e46a1,
-0x8c5ded3cb061d100,0x9140f021ad7ccc1d,0x8c5ded3cb061d100,0x9140f021ad7ccc1d,
-0x51eaeb5001babb00,0xa31819a2f34849f2,0x51eaeb5001babb00,0xa31819a2f34849f2,
-0x6e54261c72483a00,0x90aad8e28cb6c4fe,0x6e54261c72483a00,0x90aad8e28cb6c4fe,
-0xd4f0e4c41034200,0x490b4a0805470644,0xd4f0e4c41034200,0x490b4a0805470644,
-0xac29d653ff7a8500,0xa520df5af6738c09,0xac29d653ff7a8500,0xa520df5af6738c09,
-0x3296a90d3f9ba400,0x2581be1a288cb317,0x3296a90d3f9ba400,0x2581be1a288cb317,
-0x61f6b02746d19700,0xc4531582e37432a5,0x61f6b02746d19700,0xc4531582e37432a5,
-0x74ddd47d09a0a900,0x5aca50c78d1d871,0x74ddd47d09a0a900,0x5aca50c78d1d871,
-0xb288566cdee43a00,0x7e449aa01228f6cc,0xb288566cdee43a00,0x7e449aa01228f6cc,
-0xf9d7cae41d332e00,0xc6e8f5db220c113f,0xf9d7cae41d332e00,0xc6e8f5db220c113f,
-0xc088d29a5a124800,0x4b035911d199c38b,0xc088d29a5a124800,0x4b035911d199c38b,
-0xd4220bfd29dff600,0x18eec731e5133acc,0xd4220bfd29dff600,0x18eec731e5133acc,
-0x3417715266452300,0xeecdab88bc9ff9da,0x3417715266452300,0xeecdab88bc9ff9da,
-0xbc74d61ea26ac800,0x3cb69a11dd577bf,0xbc74d61ea26ac800,0x3cb69a11dd577bf,
-0xbe30149a24aa8e00,0xba34109e20ae8a04,0xbe30149a24aa8e00,0xba34109e20ae8a04,
-0x7157c3e594b22600,0xcaec785e2f099dbb,0x7157c3e594b22600,0xcaec785e2f099dbb,
-0xfc268d57ab71da00,0xf12b805aa67cd70d,0xfc268d57ab71da00,0xf12b805aa67cd70d,
-0x22a3b8391b9a8100,0xbd3c27a684051e9f,0x22a3b8391b9a8100,0xbd3c27a684051e9f,
-0x8bfc1265ee997700,0x4235dbac2750bec9,0x8bfc1265ee997700,0x4235dbac2750bec9,
-0xfb2c4a9d66b1d700,0xb36402d52ef99f48,0xfb2c4a9d66b1d700,0xb36402d52ef99f48,
-0x2c30a8b498841c00,0xb1ad35290519819d,0x2c30a8b498841c00,0xb1ad35290519819d,
-0xc41378af6bbcd700,0xda0d66b175a2c91e,0xc41378af6bbcd700,0xda0d66b175a2c91e,
-0x52535b5a08090100,0xf3f2fafba9a8a0a1,0x52535b5a08090100,0xf3f2fafba9a8a0a1,
-0x82519142c013d300,0x27f434e765b676a5,0x82519142c013d300,0x27f434e765b676a5,
-0x5c2094e8b4c87c00,0xb6ca7e025e2296ea,0x5c2094e8b4c87c00,0xb6ca7e025e2296ea,
-0x4848fefeb6b60000,0xaaaa1c1c5454e2e2,0x4848fefeb6b60000,0xaaaa1c1c5454e2e2,
-0x4f142e753a615b00,0xa0fbc19ad58eb4ef,0x4f142e753a615b00,0xa0fbc19ad58eb4ef,
-0x750c7801740d7900,0x423b4f36433a4e37,0x750c7801740d7900,0x423b4f36433a4e37,
-0x36da26cafc10ec00,0x22ce32dee804f814,0x36da26cafc10ec00,0x22ce32dee804f814,
-0x61bac31879a2db00,0x419ae3385982fb20,0x61bac31879a2db00,0x419ae3385982fb20,
-0x8eb70a33bd843900,0xe6df625bd5ec5168,0x8eb70a33bd843900,0xe6df625bd5ec5168,
-0xc6b9fa85433c7f00,0xa1de9de2245b1867,0xc6b9fa85433c7f00,0xa1de9de2245b1867,
-0xf248813bc973ba00,0xb70dc47e8c36ff45,0xf248813bc973ba00,0xb70dc47e8c36ff45,
-0xb2c5f38436417700,0xf285b3c476013740,0xb2c5f38436417700,0xf285b3c476013740,
-0x5898bb7b23e3c000,0x4c8caf6f37f7d414,0x5898bb7b23e3c000,0x4c8caf6f37f7d414,
-0x76b31edbad68c500,0x9653fe3b4d8825e0,0x76b31edbad68c500,0x9653fe3b4d8825e0,
-0xd064ac18c87cb400,0x52e62e9a4afe3682,0xd064ac18c87cb400,0x52e62e9a4afe3682,
-0x519664a3f235c700,0xa562905706c133f4,0x519664a3f235c700,0xa562905706c133f4,
-0x7b64322d56491f00,0x8d92c4dba0bfe9f6,0x7b64322d56491f00,0x8d92c4dba0bfe9f6,
-0x4f02723f703d4d00,0xcd80f0bdf2bfcf82,0x4f02723f703d4d00,0xcd80f0bdf2bfcf82,
-0xf139cd05f43cc800,0x76be4a8273bb4f87,0xf139cd05f43cc800,0x76be4a8273bb4f87,
-0xecb06539d5895c00,0x5c89d53965b0ec,0xecb06539d5895c00,0x5c89d53965b0ec,
-0xa63959c660ff9f00,0x50cfaf30960969f6,0xa63959c660ff9f00,0x50cfaf30960969f6,
-0x7d1e82e19cff6300,0xd3b02c4f3251cdae,0x7d1e82e19cff6300,0xd3b02c4f3251cdae,
-0xab28bd3e95168300,0x86059013b83bae2d,0xab28bd3e95168300,0x86059013b83bae2d,
-0x6109f39bfa926800,0x325aa0c8a9c13b53,0x6109f39bfa926800,0x325aa0c8a9c13b53,
-0xf6864a3accbc7000,0xc6b67a0afc8c4030,0xf6864a3accbc7000,0xc6b67a0afc8c4030,
-0xa9690bcb62a2c000,0xd61674b41dddbf7f,0xa9690bcb62a2c000,0xd61674b41dddbf7f,
-0xe8b25f05edb75a00,0x7c26cb917923ce94,0xe8b25f05edb75a00,0x7c26cb917923ce94,
-0x67e5da583fbd8200,0xcc4e71f3941629ab,0x67e5da583fbd8200,0xcc4e71f3941629ab,
-0x8e750df67883fb00,0x44bfc73cb24931ca,0x8e750df67883fb00,0x44bfc73cb24931ca,
-0xe451fc49ad18b500,0x95208d38dc69c471,0xe451fc49ad18b500,0x95208d38dc69c471,
-0x51a34dbfee1cf200,0x3f11fedbc4ea052,0x51a34dbfee1cf200,0x3f11fedbc4ea052,
-0x7dcaa21568dfb700,0xe0573f88f5422a9d,0x7dcaa21568dfb700,0xe0573f88f5422a9d,
-0x67d702b2d565b000,0x5beb3e8ee9598c3c,0x67d702b2d565b000,0x5beb3e8ee9598c3c,
-0xb428811da9359c00,0x9804ad318519b02c,0xb428811da9359c00,0x9804ad318519b02c,
-0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f,0xb3f31050e3a34000,0x9cdc3f7fcc8c6f2f,
-0x3d00734e734e3d00,0x4d70033e033e4d70,0x3d00734e734e3d00,0x4d70033e033e4d70,
-0xdf4c22b16efd9300,0xbe2d43d00f9cf261,0xdf4c22b16efd9300,0xbe2d43d00f9cf261,
-0x36e9419ea877df00,0xb768c01f29f65e81,0x36e9419ea877df00,0xb768c01f29f65e81,
-0xd499afe2367b4d00,0xd39ea8e5317c4a07,0xd499afe2367b4d00,0xd39ea8e5317c4a07,
-0xcfc9edeb24220600,0x5c5a7e78b7b19593,0xcfc9edeb24220600,0x5c5a7e78b7b19593,
-0xc5c3dfd91c1a0600,0x9a9c80864345595f,0xc5c3dfd91c1a0600,0x9a9c80864345595f,
-0x9387120695811400,0xdfcb5e4ad9cd584c,0x9387120695811400,0xdfcb5e4ad9cd584c,
-0xbc469d67db21fa00,0x728853a915ef34ce,0xbc469d67db21fa00,0x728853a915ef34ce,
-0x52c555c290079700,0x980f9f085acd5dca,0x52c555c290079700,0x980f9f085acd5dca,
-0xd7549f1ccb488300,0xc142890add5e9516,0xd7549f1ccb488300,0xc142890add5e9516,
-0x21a8d25b7af38900,0xc44d37be9f166ce5,0x21a8d25b7af38900,0xc44d37be9f166ce5,
-0x8bba5e6fe4d53100,0x5c6d89b83302e6d7,0x8bba5e6fe4d53100,0x5c6d89b83302e6d7,
-0xc565df7fba1aa000,0x9f3f8525e040fa5a,0xc565df7fba1aa000,0x9f3f8525e040fa5a,
-0x17c457849340d300,0x70a330e3f427b467,0x17c457849340d300,0x70a330e3f427b467,
-0xac286eea46c28400,0x6de9af2b870345c1,0xac286eea46c28400,0x6de9af2b870345c1,
-0xf96f29bf46d09600,0xbe286ef80197d147,0xf96f29bf46d09600,0xbe286ef80197d147,
-0xf444bb0bff4fb000,0x76c639897dcd3282,0xf444bb0bff4fb000,0x76c639897dcd3282,
-0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe,0xc4f93805c1fc3d00,0x3a07c6fb3f02c3fe,
-0x58ca9a0850c29200,0x861444d68e1c4cde,0x58ca9a0850c29200,0x861444d68e1c4cde,
-0x5e045208560c5a00,0x6832643e603a6c36,0x5e045208560c5a00,0x6832643e603a6c36,
-0xa9aac8cb62610300,0x1a197b78d1d2b0b3,0xa9aac8cb62610300,0x1a197b78d1d2b0b3,
-0xf87dac29d1548500,0x47c213966eeb3abf,0xf87dac29d1548500,0x47c213966eeb3abf,
-0x663ffea7c1985900,0xc89150096f36f7ae,0x663ffea7c1985900,0xc89150096f36f7ae,
-0x926e3ec250acfc00,0x897525d94bb7e71b,0x926e3ec250acfc00,0x897525d94bb7e71b,
-0x208f02ad8d22af00,0x369914bb9b34b916,0x208f02ad8d22af00,0x369914bb9b34b916,
-0x2a0b24052f0e2100,0xdffed1f0dafbd4f5,0x2a0b24052f0e2100,0xdffed1f0dafbd4f5,
-0xf1bccd8d7c31400,0xc3d700141b0fd8cc,0xf1bccd8d7c31400,0xc3d700141b0fd8cc,
-0xce0aca0ec004c400,0xe521e125eb2fef2b,0xce0aca0ec004c400,0xe521e125eb2fef2b,
-0xdd97f1bb662c4a00,0x96dcbaf02d67014b,0xdd97f1bb662c4a00,0x96dcbaf02d67014b,
-0x8756fd2cab7ad100,0xbda71a027f65d8c,0x8756fd2cab7ad100,0xbda71a027f65d8c,
-0x410b206a2b614a00,0xd69cb7fdbcf6dd97,0x410b206a2b614a00,0xd69cb7fdbcf6dd97,
-0x754acfff8ab5300,0x2f7c84d7d0837b28,0x754acfff8ab5300,0x2f7c84d7d0837b28,
-0xa9b4766bc2df1d00,0xeef3312c85985a47,0xa9b4766bc2df1d00,0xeef3312c85985a47,
-0x49820dc68f44cb00,0x8e45ca0148830cc7,0x49820dc68f44cb00,0x8e45ca0148830cc7,
-0xe97cc752bb2e9500,0x7ce952c72ebb0095,0xe97cc752bb2e9500,0x7ce952c72ebb0095,
-0x687d9c89e1f41500,0xd2c726335b4eafba,0x687d9c89e1f41500,0xd2c726335b4eafba,
-0x73eadc4536af9900,0x3da4920b78e1d74e,0x73eadc4536af9900,0x3da4920b78e1d74e,
-0xb8ad0a1fa7b21500,0x1005a2b70f1abda8,0xb8ad0a1fa7b21500,0x1005a2b70f1abda8,
-0x44f3fd4a0eb9b700,0xf4434dfabe0907b0,0x44f3fd4a0eb9b700,0xf4434dfabe0907b0,
-0x4e97f42d63bad900,0xa87112cb855c3fe6,0x4e97f42d63bad900,0xa87112cb855c3fe6,
-0x4d7e45763b083300,0x86b58ebdf0c3f8cb,0x4d7e45763b083300,0x86b58ebdf0c3f8cb,
-0x73b75f9be82cc400,0x71b55d99ea2ec602,0x73b75f9be82cc400,0x71b55d99ea2ec602,
-0x7b7ca3a4dfd80700,0x86815e592225fafd,0x7b7ca3a4dfd80700,0x86815e592225fafd,
-0x24ebe6290dc2cf00,0xae616ca38748458a,0x24ebe6290dc2cf00,0xae616ca38748458a,
-0x243cbba3879f1800,0xb3ab2c3410088f97,0x243cbba3879f1800,0xb3ab2c3410088f97,
-0xed17fd07ea10fa00,0x33c923d934ce24de,0xed17fd07ea10fa00,0x33c923d934ce24de,
-0x33b20f8ebd3c8100,0x9e1fa22310912cad,0x33b20f8ebd3c8100,0x9e1fa22310912cad,
-0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d,0x9ef0026cf29c6e00,0xa3cd3f51cfa1533d,
-0x7768c0dfa8b71f00,0xe7f8504f38278f90,0x7768c0dfa8b71f00,0xe7f8504f38278f90,
-0x375bb2dee9856c00,0x2844adc1f69a731f,0x375bb2dee9856c00,0x2844adc1f69a731f,
-0xaf992f19b6803600,0x93a513258abc0a3c,0xaf992f19b6803600,0x93a513258abc0a3c,
-0x7a0f87f288fd7500,0xf1840c790376fe8b,0x7a0f87f288fd7500,0xf1840c790376fe8b,
-0x8015c752d2479500,0xcc598b1e9e0bd94c,0x8015c752d2479500,0xcc598b1e9e0bd94c,
-0x8023be1d9d3ea300,0x48eb76d555f66bc8,0x8023be1d9d3ea300,0x48eb76d555f66bc8,
-0x9c2f21920ebdb300,0x15a6a81b87343a89,0x9c2f21920ebdb300,0x15a6a81b87343a89,
-0x30d356b58566e300,0x8e6de80b3bd85dbe,0x30d356b58566e300,0x8e6de80b3bd85dbe,
-0xa9a6222d848b0f00,0xded1555af3fc7877,0xa9a6222d848b0f00,0xded1555af3fc7877,
-0xa7c9d9b7107e6e00,0x76180866c1afbfd1,0xa7c9d9b7107e6e00,0x76180866c1afbfd1,
-0x6c02f59bf7996e00,0x8ae4137d117f88e6,0x6c02f59bf7996e00,0x8ae4137d117f88e6,
-0xb31f2884379bac00,0xcc6057fb48e4d37f,0xb31f2884379bac00,0xcc6057fb48e4d37f,
-0x24dcd62e0af2f800,0x89717b83a75f55ad,0x24dcd62e0af2f800,0x89717b83a75f55ad,
-0xe29fdca1433e7d00,0xe79ad9a4463b7805,0xe29fdca1433e7d00,0xe79ad9a4463b7805,
-0x4f75caf0bf853a00,0xcdf748723d07b882,0x4f75caf0bf853a00,0xcdf748723d07b882,
-0x9ed3d69b05484d00,0x6924216cf2bfbaf7,0x9ed3d69b05484d00,0x6924216cf2bfbaf7,
-0x4bba837239c8f100,0x4bba837239c8f100,0x4bba837239c8f100,0x4bba837239c8f100,
-0xf0fe2a24d4da0e00,0x353befe1111fcbc5,0xf0fe2a24d4da0e00,0x353befe1111fcbc5,
-0xa1c3a5c766046200,0xb6d4b2d071137517,0xa1c3a5c766046200,0xb6d4b2d071137517,
-0x733a94ddaee74900,0xfeb71950236ac48d,0x733a94ddaee74900,0xfeb71950236ac48d,
-0x43b2906122d3f100,0x7081a35211e0c233,0x43b2906122d3f100,0x7081a35211e0c233,
-0x7281906311e2f300,0x9c6f7e8dff0c1dee,0x7281906311e2f300,0x9c6f7e8dff0c1dee,
-0x681709761e617f00,0x1a657b046c130d72,0x681709761e617f00,0x1a657b046c130d72,
-0xa7876040e7c7200,0xc7e7002087a7406,0xa7876040e7c7200,0xc7e7002087a7406,
-0xe747d2729535a000,0x379702a245e570d0,0xe747d2729535a000,0x379702a245e570d0,
-0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42,0x1914a6abb2bf0d00,0x5b56e4e9f0fd4f42,
-0xea8a4020caaa600,0x1bbdb11719bfb315,0xea8a4020caaa600,0x1bbdb11719bfb315,
-0xfd5343ed10beae00,0x832d3d936ec0d07e,0xfd5343ed10beae00,0x832d3d936ec0d07e,
-0xa5a5b3b316160000,0x71716767c2c2d4d4,0xa5a5b3b316160000,0x71716767c2c2d4d4,
-0x4ae8c262288aa00,0x2e84a60c08a2802a,0x4ae8c262288aa00,0x2e84a60c08a2802a,
-0xb5017ace7bcfb400,0xb4007bcf7aceb501,0xb5017ace7bcfb400,0xb4007bcf7aceb501,
-0xdddf42429f9d000,0xd2022bfbf6260fdf,0xdddf42429f9d000,0xd2022bfbf6260fdf,
-0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21,0xf3c9ffc5360c3a00,0xd2e8dee4172d1b21,
-0x966f847deb12f900,0xf60fe41d8b729960,0x966f847deb12f900,0xf60fe41d8b729960,
-0xeca5ffb65a134900,0xe5acf6bf531a4009,0xeca5ffb65a134900,0xe5acf6bf531a4009,
-0xd286c49042165400,0x72266430e2b6f4a0,0xd286c49042165400,0x72266430e2b6f4a0,
-0xb02146d767f69100,0x62f39405b52443d2,0xb02146d767f69100,0x62f39405b52443d2,
-0xc563b214d177a600,0xe2449533f6508127,0xc563b214d177a600,0xe2449533f6508127,
-0x8d48ae6be623c500,0x509573b63bfe18dd,0x8d48ae6be623c500,0x509573b63bfe18dd,
-0xdc702d815df1ac00,0xf75b06aa76da872b,0xdc702d815df1ac00,0xf75b06aa76da872b,
-0x7452b395e1c72600,0x90b657710523c2e4,0x7452b395e1c72600,0x90b657710523c2e4,
-0xb8480cfc44b4f000,0x50a0e414ac5c18e8,0xb8480cfc44b4f000,0x50a0e414ac5c18e8,
-0xc11072a362b3d100,0xc61775a465b4d607,0xc11072a362b3d100,0xc61775a465b4d607,
-0x97bfa28a1d352800,0xc9e1fcd4436b765e,0x97bfa28a1d352800,0xc9e1fcd4436b765e,
-0xf62cd00afc26da00,0x429864be48926eb4,0xf62cd00afc26da00,0x429864be48926eb4,
-0x340cdee6d2ea3800,0x2b13c1f9cdf5271f,0x340cdee6d2ea3800,0x2b13c1f9cdf5271f,
-0x5fc8c156099e9700,0xd84f46d18e191087,0x5fc8c156099e9700,0xd84f46d18e191087,
-0x4cf36cd39f20bf00,0x11ae318ec27de25d,0x4cf36cd39f20bf00,0x11ae318ec27de25d,
-0xed2f2def02c0c200,0xaf6d6fad40828042,0xed2f2def02c0c200,0xaf6d6fad40828042,
-0x190da8bca5b11400,0xbfab0e1a0317b2a6,0x190da8bca5b11400,0xbfab0e1a0317b2a6,
-0x6d276e2449034a00,0x4309400a672d642e,0x6d276e2449034a00,0x4309400a672d642e,
-0xb3bda2ac1f110e00,0x323c232d9e908f81,0xb3bda2ac1f110e00,0x323c232d9e908f81,
-0x30e213c1f123d200,0x6cbe4f9dad7f8e5c,0x30e213c1f123d200,0x6cbe4f9dad7f8e5c,
-0x97ec790295ee7b00,0x4d36a3d84f34a1da,0x97ec790295ee7b00,0x4d36a3d84f34a1da,
-0x5cebbc0b57e0b700,0x6bdc8b3c60d78037,0x5cebbc0b57e0b700,0x6bdc8b3c60d78037,
-0x30380f07373f0800,0x60685f57676f5850,0x30380f07373f0800,0x60685f57676f5850,
-0xdc3dc121fd1ce00,0xe12f30fef33d22ec,0xdc3dc121fd1ce00,0xe12f30fef33d22ec,
-0xc7894a04c38d4e00,0x1d5390de195794da,0xc7894a04c38d4e00,0x1d5390de195794da,
-0xbb19ac0eb517a200,0x1bb90cae15b702a0,0xbb19ac0eb517a200,0x1bb90cae15b702a0,
-0x1e2c3d0f11233200,0xc3e2f1d03312012,0x1e2c3d0f11233200,0xc3e2f1d03312012,
-0x7af3e56c169f8900,0xd84921b61e8fe77,0x7af3e56c169f8900,0xd84921b61e8fe77,
-0xaa72409832ead800,0xfe2614cc66be8c54,0xaa72409832ead800,0xfe2614cc66be8c54,
-0xdcdd80815d5c0100,0xf2f3aeaf73722f2e,0xdcdd80815d5c0100,0xf2f3aeaf73722f2e,
-0xd8eae2d20a38300,0xbb38189b961535b6,0xd8eae2d20a38300,0xbb38189b961535b6,
-0x5add65e2b83f8700,0x68139bee463db5c,0x5add65e2b83f8700,0x68139bee463db5c,
-0x3b8450efd46bbf00,0xf946922d16a97dc2,0x3b8450efd46bbf00,0xf946922d16a97dc2,
-0x2d903885a815bd00,0x79c46cd1fc41e954,0x2d903885a815bd00,0x79c46cd1fc41e954,
-0xe3111def0cfef200,0xb3414dbf5caea250,0xe3111def0cfef200,0xb3414dbf5caea250,
-0xe19e2e51b0cf7f00,0x778c8b7562999e6,0xe19e2e51b0cf7f00,0x778c8b7562999e6,
-0x974cd803944fdb00,0x449f0bd0479c08d3,0x974cd803944fdb00,0x449f0bd0479c08d3,
-0xd92bf002db29f200,0x6f42fdd04f62ddf,0xd92bf002db29f200,0x6f42fdd04f62ddf,
-0xcb56a538f36e9d00,0x4996af73ca152cf,0xcb56a538f36e9d00,0x4996af73ca152cf,
-0x26238386a0a50500,0x838626230500a0a5,0x26238386a0a50500,0x838626230500a0a5,
-0xd6843c6eb8ea5200,0x7c2e96c41240f8aa,0xd6843c6eb8ea5200,0x7c2e96c41240f8aa,
-0x6f41e0cea18f2e00,0x755bfad4bb95341a,0x6f41e0cea18f2e00,0x755bfad4bb95341a,
-0x982e2e9800b6b600,0x67d1d167ff4949ff,0x982e2e9800b6b600,0x67d1d167ff4949ff,
-0xc2acd5bb79176e00,0xe688f19f5d334a24,0xc2acd5bb79176e00,0xe688f19f5d334a24,
-0x44aa14fabe50ee00,0x9876c826628c32dc,0x44aa14fabe50ee00,0x9876c826628c32dc,
-0x34a21482b6209600,0x63f543d5e177c157,0x34a21482b6209600,0x63f543d5e177c157,
-0x620cb8d6b4da6e00,0x46289cf290fe4a24,0x620cb8d6b4da6e00,0x46289cf290fe4a24,
-0xef7d0e9c73e19200,0x9f0d7eec0391e270,0xef7d0e9c73e19200,0x9f0d7eec0391e270,
-0x90f17d1c8ced6100,0xb0d15d3caccd4120,0x90f17d1c8ced6100,0xb0d15d3caccd4120,
-0xba7cd016ac6ac600,0xe4228e48f234985e,0xba7cd016ac6ac600,0xe4228e48f234985e,
-0xdb88ce9d46155300,0xa591f4c97c482d1,0xdb88ce9d46155300,0xa591f4c97c482d1,
-0xccf6734985bf3a00,0x7f45c0fa360c89b3,0xccf6734985bf3a00,0x7f45c0fa360c89b3,
-0xa6fee5bd1b435800,0xe4bca7ff59011a42,0xa6fee5bd1b435800,0xe4bca7ff59011a42,
-0x3ab029a399138a00,0x41cb52d8e268f17b,0x3ab029a399138a00,0x41cb52d8e268f17b,
-0x9b924d44dfd60900,0x343de2eb7079a6af,0x9b924d44dfd60900,0x343de2eb7079a6af,
-0x44ddc9591d84900,0x7039a8e1e5ac3d74,0x44ddc9591d84900,0x7039a8e1e5ac3d74,
-0xa1b1f8e849591000,0x617138288999d0c0,0xa1b1f8e849591000,0x617138288999d0c0,
-0xe26b4ac321a88900,0x1198b930d25b7af3,0xe26b4ac321a88900,0x1198b930d25b7af3,
-0x5940160f564f1900,0x372e78613821776e,0x5940160f564f1900,0x372e78613821776e,
-0xdbb2127ba0c96900,0x6a03a3ca1178d8b1,0xdbb2127ba0c96900,0x6a03a3ca1178d8b1,
-0x92639c6dff0ef100,0x72837c8d1fee11e0,0x92639c6dff0ef100,0x72837c8d1fee11e0,
-0xafa2bfb21d100d00,0x878a979a35382528,0xafa2bfb21d100d00,0x878a979a35382528,
-0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6,0xc9ede8cc05212400,0x1f3b3e1ad3f7f2d6,
-0xa9a28289202b0b00,0x4f44646fc6cdede6,0xa9a28289202b0b00,0x4f44646fc6cdede6,
-0xa4f592c367365100,0x6b3a5d0ca8f99ecf,0xa4f592c367365100,0x6b3a5d0ca8f99ecf,
-0xe3304c9f7cafd300,0xfd2e528162b1cd1e,0xe3304c9f7cafd300,0xfd2e528162b1cd1e,
-0xe6ca0529cfe32c00,0xdff33c10f6da1539,0xe6ca0529cfe32c00,0xdff33c10f6da1539,
-0xcd403cb17cf18d00,0xc74a36bb76fb870a,0xcd403cb17cf18d00,0xc74a36bb76fb870a,
-0xeda64f04e9a24b00,0x92d9307b96dd347f,0xeda64f04e9a24b00,0x92d9307b96dd347f,
-0x86be7941c7ff3800,0xf6ce0931b78f4870,0x86be7941c7ff3800,0xf6ce0931b78f4870,
-0x71a4a87d0cd9d500,0xcb1e12c7b6636fba,0x71a4a87d0cd9d500,0xcb1e12c7b6636fba,
-0x757d848cf9f10800,0x1911e8e0959d646c,0x757d848cf9f10800,0x1911e8e0959d646c,
-0xf0349e5aaa6ec400,0x9cd67a353973df9,0xf0349e5aaa6ec400,0x9cd67a353973df9,
-0x2d18d2e7caff3500,0x72478db895a06a5f,0x2d18d2e7caff3500,0x72478db895a06a5f,
-0x9e148a0a941e800,0x31d970989179d038,0x9e148a0a941e800,0x31d970989179d038,
-0xac55af56fa03f900,0x38c13bc26e976d94,0xac55af56fa03f900,0x38c13bc26e976d94,
-0x3c04a898a49c300,0xdc1f955655961cdf,0x3c04a898a49c300,0xdc1f955655961cdf,
-0x71cbc97302b8ba00,0x3b9bb0170cac872,0x71cbc97302b8ba00,0x3b9bb0170cac872,
-0xcecdf6f53b380300,0x7a7942418f8cb7b4,0xcecdf6f53b380300,0x7a7942418f8cb7b4,
-0x85d9f7ab2e725c00,0x48143a66e3bf91cd,0x85d9f7ab2e725c00,0x48143a66e3bf91cd,
-0x7275313644430700,0x90e4a4d3f387c7b,0x7275313644430700,0x90e4a4d3f387c7b,
-0x8e1fef7ef0619100,0x3aab5bca44d525b4,0x8e1fef7ef0619100,0x3aab5bca44d525b4,
-0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc,0x11e28e7d6c9ff300,0xdd2e42b1a0533fcc,
-0x933bcb63f058a800,0xd27a8a22b119e941,0x933bcb63f058a800,0xd27a8a22b119e941,
-0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc,0x2c00012d012d2c00,0xf0dcddf1ddf1f0dc,
-0x469033e5a375d600,0xd701a27432e44791,0x469033e5a375d600,0xd701a27432e44791,
-0x5237fb9ecca96500,0x1f7ab6d381e4284d,0x5237fb9ecca96500,0x1f7ab6d381e4284d,
-0x7e7f3c3d43420100,0x8180c3c2bcbdfeff,0x7e7f3c3d43420100,0x8180c3c2bcbdfeff,
-0x68688f8fe7e70000,0xe7e7000068688f8f,0x68688f8fe7e70000,0xe7e7000068688f8f,
-0x2211d8ebc9fa3300,0xddee27143605ccff,0x2211d8ebc9fa3300,0xddee27143605ccff,
-0x4e4e8484caca0000,0xf2f238387676bcbc,0x4e4e8484caca0000,0xf2f238387676bcbc,
-0x543dbad387ee6900,0xd3ba3d540069ee87,0x543dbad387ee6900,0xd3ba3d540069ee87,
-0xcccc1212dede0000,0x1b1bc5c50909d7d7,0xcccc1212dede0000,0x1b1bc5c50909d7d7,
-0xac45719834dde900,0x678eba53ff1622cb,0xac45719834dde900,0x678eba53ff1622cb,
-0x4b4b030348480000,0xfdfdb5b5fefeb6b6,0x4b4b030348480000,0xfdfdb5b5fefeb6b6,
-0x4e1d21723c6f5300,0x580b37642a794516,0x4e1d21723c6f5300,0x580b37642a794516,
-0x8a8a1e1e94940000,0xeaea7e7ef4f46060,0x8a8a1e1e94940000,0xeaea7e7ef4f46060,
-0xa1a8a5ac0d040900,0x8f868b82232a272e,0xa1a8a5ac0d040900,0x8f868b82232a272e,
-0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d,0xf9f9b7b74e4e0000,0xe4e4aaaa53531d1d,
-0xcbeecce922072500,0x8bae8ca962476540,0xcbeecce922072500,0x8bae8ca962476540,
-0xd5d53434e1e10000,0x606e7e73232d3d3,0xd5d53434e1e10000,0x606e7e73232d3d3,
-0x1897d8574fc08f00,0x36b9f67961eea12e,0x1897d8574fc08f00,0x36b9f67961eea12e,
-0x4949dede97970000,0xf8f86f6f2626b1b1,0x4949dede97970000,0xf8f86f6f2626b1b1,
-0x34e3f72014c3d700,0x35e2f62115c2d601,0x34e3f72014c3d700,0x35e2f62115c2d601,
-0x23f2e13112c3d00,0x576a7b4644796855,0x23f2e13112c3d00,0x576a7b4644796855,
-0x9a92424ad0d80800,0x6e66b6be242cfcf4,0x9a92424ad0d80800,0x6e66b6be242cfcf4,
-0x7874c9c5bdb10c00,0xe3ef525e262a979b,0x7874c9c5bdb10c00,0xe3ef525e262a979b,
-0x1083a93a2ab99300,0x891a30a3b3200a99,0x1083a93a2ab99300,0x891a30a3b3200a99,
-0xa4aa5d53f7f90e00,0x737d8a84202ed9d7,0xa4aa5d53f7f90e00,0x737d8a84202ed9d7,
-0x8cd5540d81d85900,0x851d089055cdd84,0x8cd5540d81d85900,0x851d089055cdd84,
-0x4047060141460700,0x4542030444430205,0x4047060141460700,0x4542030444430205,
-0x4fa4be551af1eb00,0x2ac1db307f948e65,0x4fa4be551af1eb00,0x2ac1db307f948e65,
-0xdded3303deee3000,0xdded3303deee3000,0xdded3303deee3000,0xdded3303deee3000,
-0x90a85868f8c0300,0x2122adaea7a42b28,0x90a85868f8c0300,0x2122adaea7a42b28,
-0x901f3ab525aa8f00,0xa827028d1d92b738,0x901f3ab525aa8f00,0xa827028d1d92b738,
-0x4c12b4eaa6f85e00,0x5709aff1bde3451b,0x4c12b4eaa6f85e00,0x5709aff1bde3451b,
-0x7025e1b4c4915500,0x90c501542471b5e0,0x7025e1b4c4915500,0x90c501542471b5e0,
-0xc1b45227e6937500,0x4336d0a56411f782,0xc1b45227e6937500,0x4336d0a56411f782,
-0xfe1011ff01efee00,0x28c6c729d73938d6,0xfe1011ff01efee00,0x28c6c729d73938d6,
-0x8228ba109238aa00,0x7ad3f9517bd2f85,0x8228ba109238aa00,0x7ad3f9517bd2f85,
-0xb79b200cbb972c00,0x19358ea2153982ae,0xb79b200cbb972c00,0x19358ea2153982ae,
-0x6fa25b96f934cd00,0x458871bcd31ee72a,0x6fa25b96f934cd00,0x458871bcd31ee72a,
-0x21e2c40726e5c300,0xf13214d7f63513d0,0x21e2c40726e5c300,0xf13214d7f63513d0,
-0x8c8aded854520600,0xdbdd898f03055157,0x8c8aded854520600,0xdbdd898f03055157,
-0x6e190d7a14637700,0x92e5f186e89f8bfc,0x6e190d7a14637700,0x92e5f186e89f8bfc,
-0x4fdd099bd4469200,0x168450c28d1fcb59,0x4fdd099bd4469200,0x168450c28d1fcb59,
-0xec7e92927eec00,0x5db123cfcf23b15d,0xec7e92927eec00,0x5db123cfcf23b15d,
-0x7e10177907696e00,0xe08e89e799f7f09e,0x7e10177907696e00,0xe08e89e799f7f09e,
-0xbb5dd2348f69e600,0xcb2da244ff199670,0xbb5dd2348f69e600,0xcb2da244ff199670,
-0x87f62151d6a7700,0x88ffe2959deaf780,0x87f62151d6a7700,0x88ffe2959deaf780,
-0x791cb9dca5c06500,0x5e3b9efb82e74227,0x791cb9dca5c06500,0x5e3b9efb82e74227,
-0x87b3a39710243400,0xa49080b433071723,0x87b3a39710243400,0xa49080b433071723,
-0xde2ec737e919f000,0x6f9f768658a841b1,0xde2ec737e919f000,0x6f9f768658a841b1,
-0x5ab74dadf71ae00,0x228c53fdf8568927,0x5ab74dadf71ae00,0x228c53fdf8568927,
-0xbb832018a39b3800,0x84bc1f279ca4073f,0xbb832018a39b3800,0x84bc1f279ca4073f,
-0xb0f8b2fa4a024800,0x84cc86ce7e367c34,0xb0f8b2fa4a024800,0x84cc86ce7e367c34,
-0x6f1e42335c2d7100,0xc0b1ed9cf382deaf,0x6f1e42335c2d7100,0xc0b1ed9cf382deaf,
-0x7a8ea0542edaf400,0xcd3917e3996d43b7,0x7a8ea0542edaf400,0xcd3917e3996d43b7,
-0x7f33175b24684c00,0x3d715519662a0e42,0x7f33175b24684c00,0x3d715519662a0e42,
-0xf7c41221d6e53300,0x8dbe685bac9f497a,0xf7c41221d6e53300,0x8dbe685bac9f497a,
-0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff,0x4fbbf4f4bb4f00,0xffb0440b0b44b0ff,
-0x8405f170f4758100,0xd455a120a425d150,0x8405f170f4758100,0xd455a120a425d150,
-0xb240a85ae81af200,0x699b738133c129db,0xb240a85ae81af200,0x699b738133c129db,
-0xdead5724fa897300,0x592ad0a37d0ef487,0xdead5724fa897300,0x592ad0a37d0ef487,
-0x68201c543c744800,0x723a064e266e521a,0x68201c543c744800,0x723a064e266e521a,
-0x219acb7051eabb00,0x9b2071caeb5001ba,0x219acb7051eabb00,0x9b2071caeb5001ba,
-0x80b75562e2d53700,0x536486b13106e4d3,0x80b75562e2d53700,0x536486b13106e4d3,
-0x6d91f9056894fc00,0x6995fd016c90f804,0x6d91f9056894fc00,0x6995fd016c90f804,
-0x5cb17895c924ed00,0x668b42aff31ed73a,0x5cb17895c924ed00,0x668b42aff31ed73a,
-0x5a4f55451f0a100,0x1abbea4b4eefbe1f,0x5a4f55451f0a100,0x1abbea4b4eefbe1f,
-0x32bcaa2416988e00,0x73fdeb6557d9cf41,0x32bcaa2416988e00,0x73fdeb6557d9cf41,
-0xda3d44a3799ee700,0x43a4dd3ae0077e99,0xda3d44a3799ee700,0x43a4dd3ae0077e99,
-0xf9d25b7089a22b00,0x6e45cce71e35bc97,0xf9d25b7089a22b00,0x6e45cce71e35bc97,
-0x67c341e58226a400,0xe94dcf6b0ca82a8e,0x67c341e58226a400,0xe94dcf6b0ca82a8e,
-0xdbae7b0ed5a07500,0x205580f52e5b8efb,0xdbae7b0ed5a07500,0x205580f52e5b8efb,
-0x5d8528f8a57dd00,0x24f973aeab76fc21,0x5d8528f8a57dd00,0x24f973aeab76fc21,
-0xac027cd27ed0ae00,0xea0de70dc720ca2,0xac027cd27ed0ae00,0xea0de70dc720ca2,
-0x1c90da564ac68c00,0x911d57dbc74b018d,0x1c90da564ac68c00,0x911d57dbc74b018d,
-0xc04c5ad6169a8c00,0x1a96800ccc4056da,0xc04c5ad6169a8c00,0x1a96800ccc4056da,
-0xfadf2c09f3d62500,0x3411e2c73d18ebce,0xfadf2c09f3d62500,0x3411e2c73d18ebce,
-0xcf77e35b942cb800,0xb901952de25ace76,0xcf77e35b942cb800,0xb901952de25ace76,
-0xf46a9806f26c9e00,0x31af5dc337a95bc5,0xf46a9806f26c9e00,0x31af5dc337a95bc5,
-0xf0fee9e717190e00,0xb4baada3535d4a44,0xf0fee9e717190e00,0xb4baada3535d4a44,
-0x845b06d95d82df00,0xf12e73ac28f7aa75,0x845b06d95d82df00,0xf12e73ac28f7aa75,
-0x2b745b042f705f00,0xda85aaf5de81aef1,0x2b745b042f705f00,0xda85aaf5de81aef1,
-0x2f65561c33794a00,0x713b08426d27145e,0x2f65561c33794a00,0x713b08426d27145e,
-0x21f25586a774d300,0x33e04794b566c112,0x21f25586a774d300,0x33e04794b566c112,
-0xb3d27d1cafce6100,0xe0812e4ffc9d3253,0xb3d27d1cafce6100,0xe0812e4ffc9d3253,
-0x11fc34d9c825ed00,0xa74a826f7e935bb6,0x11fc34d9c825ed00,0xa74a826f7e935bb6,
-0x596d77431a2e3400,0x3f0b11257c485266,0x596d77431a2e3400,0x3f0b11257c485266,
-0x5c7f684b17342300,0x1c3f280b57746340,0x5c7f684b17342300,0x1c3f280b57746340,
-0xfee4b5af514b1a00,0x554f1e04fae0b1ab,0xfee4b5af514b1a00,0x554f1e04fae0b1ab,
-0x573c7a11462d6b00,0x5932741f4823650e,0x573c7a11462d6b00,0x5932741f4823650e,
-0x624e476b09252c00,0xe222b076549406c,0x624e476b09252c00,0xe222b076549406c,
-0xf58f6e14e19b7a00,0x2258b9c3364cadd7,0xf58f6e14e19b7a00,0x2258b9c3364cadd7,
-0x24e65a98bc7ec200,0x75b70bc9ed2f9351,0x24e65a98bc7ec200,0x75b70bc9ed2f9351,
-0xafb4445ff0eb1b00,0x8c97677cd3c83823,0xafb4445ff0eb1b00,0x8c97677cd3c83823,
-0xd2277f8a58adf500,0xe81d45b06297cf3a,0xd2277f8a58adf500,0xe81d45b06297cf3a,
-0xdef1b39c426d2f00,0x113e7c538da2e0cf,0xdef1b39c426d2f00,0x113e7c538da2e0cf,
-0x99667d821be4ff00,0xce312ad54cb3a857,0x99667d821be4ff00,0xce312ad54cb3a857,
-0xc62dfe15d338eb00,0x5eb5668d4ba07398,0xc62dfe15d338eb00,0x5eb5668d4ba07398,
-0xfbe60d1de6fb100,0x3e8f51e0ef5e8031,0xfbe60d1de6fb100,0x3e8f51e0ef5e8031,
-0x63d544f29127b600,0x3b52492f147d660,0x63d544f29127b600,0x3b52492f147d660,
-0x2ce728e3cf04cb00,0xaf64ab604c874883,0x2ce728e3cf04cb00,0xaf64ab604c874883,
-0xefda7a4fa0953500,0x8bbe1e2bc4f15164,0xefda7a4fa0953500,0x8bbe1e2bc4f15164,
-0x160f435a4c551900,0x3128647d6b723e27,0x160f435a4c551900,0x3128647d6b723e27,
-0x6ef775ec821b9900,0xcf56d44d23ba38a1,0x6ef775ec821b9900,0xcf56d44d23ba38a1,
-0xde0f11c11fced00,0xa74a5bb6bb5647aa,0xde0f11c11fced00,0xa74a5bb6bb5647aa,
-0xdb953f71aae44e00,0x82cc6628f3bd1759,0xdb953f71aae44e00,0x82cc6628f3bd1759,
-0xf42b37e81cc3df00,0xd30c10cf3be4f827,0xf42b37e81cc3df00,0xd30c10cf3be4f827,
-0x7c51c6eb97ba2d00,0x406dfad7ab86113c,0x7c51c6eb97ba2d00,0x406dfad7ab86113c,
-0x1c39ffdac6e32500,0x604583a6ba9f597c,0x1c39ffdac6e32500,0x604583a6ba9f597c,
-0x8ef7126be59c7900,0xfb82671e90e90c75,0x8ef7126be59c7900,0xfb82671e90e90c75,
-0xffafaafa05555000,0xfcaca9f906565303,0xffafaafa05555000,0xfcaca9f906565303,
-0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc,0x3f041b2b142f300,0xcf3c8d7e7d8e3fcc,
-0x9f4aa277e83dd500,0x1fca22f768bd5580,0x9f4aa277e83dd500,0x1fca22f768bd5580,
-0x6b01b6dcb7dd6a00,0x244ef993f892254f,0x6b01b6dcb7dd6a00,0x244ef993f892254f,
-0x76f9da5523ac8f00,0xaa250689ff7053dc,0x76f9da5523ac8f00,0xaa250689ff7053dc,
-0x166bf78a9ce17d00,0x7d009ce1f78a166b,0x166bf78a9ce17d00,0x7d009ce1f78a166b,
-0x30e6e33505d3d600,0x78aeab7d4d9b9e48,0x30e6e33505d3d600,0x78aeab7d4d9b9e48,
-0x20b2a03212809200,0xa93b29bb9b091b89,0x20b2a03212809200,0xa93b29bb9b091b89,
-0xf3aff6aa59055c00,0x570b520efda1f8a4,0xf3aff6aa59055c00,0x570b520efda1f8a4,
-0xfba60c51aaf75d00,0xb5e8421fe4b9134e,0xfba60c51aaf75d00,0xb5e8421fe4b9134e,
-0xa3628849ea2bc100,0xa0618b4ae928c203,0xa3628849ea2bc100,0xa0618b4ae928c203,
-0xd1fc2d00d1fc2d00,0xcee3321fcee3321f,0xd1fc2d00d1fc2d00,0xcee3321fcee3321f,
-0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46,0x4d00a5e8a5e84d00,0xb46e3aee3ae0b46,
-0x8647dc1d9b5ac100,0xa465fe3fb978e322,0x8647dc1d9b5ac100,0xa465fe3fb978e322,
-0xb9bd84843d39000,0x2dbdfe6e65f5b626,0xb9bd84843d39000,0x2dbdfe6e65f5b626,
-0x82ab577efcd52900,0x5a738fa6240df1d8,0x82ab577efcd52900,0x5a738fa6240df1d8,
-0xb1f9246cdd954800,0x18508dc5743ce1a9,0xb1f9246cdd954800,0x18508dc5743ce1a9,
-0x5697814117d6c00,0xed8190fcf99584e8,0x5697814117d6c00,0xed8190fcf99584e8,
-0x2249e78caec56b00,0x660da3c8ea812f44,0x2249e78caec56b00,0x660da3c8ea812f44,
-0x93f0610291f26300,0xe6851477e4871675,0x93f0610291f26300,0xe6851477e4871675,
-0x4a84c8064c82ce00,0x65abe72963ade12f,0x4a84c8064c82ce00,0x65abe72963ade12f,
-0x8670ce38be48f600,0x7f8937c147b10ff9,0x8670ce38be48f600,0x7f8937c147b10ff9,
-0xbfd2cea31c716d00,0x6e031f72cda0bcd1,0xbfd2cea31c716d00,0x6e031f72cda0bcd1,
-0x89167be46df29f00,0xd74825ba33acc15e,0x89167be46df29f00,0xd74825ba33acc15e,
-0x6b3d2472194f5600,0xe7b1a8fe95c3da8c,0x6b3d2472194f5600,0xe7b1a8fe95c3da8c,
-0x80ce80ce4e004e00,0x501e501e9ed09ed0,0x80ce80ce4e004e00,0x501e501e9ed09ed0,
-0x5ac31089d34a9900,0x77ee3da4fe67b42d,0x5ac31089d34a9900,0x77ee3da4fe67b42d,
-0x775398bccbef2400,0x2b0fc4e097b3785c,0x775398bccbef2400,0x2b0fc4e097b3785c,
-0xa7f21742e5b05500,0x5104e1b41346a3f6,0xa7f21742e5b05500,0x5104e1b41346a3f6,
-0xceb2fc8c423e700,0x29ce0aede106c225,0xceb2fc8c423e700,0x29ce0aede106c225,
-0x67ffe57d1a829800,0x56ced44c2bb3a931,0x67ffe57d1a829800,0x56ced44c2bb3a931,
-0xb42767f440d39300,0x59ca8a19ad3e7eed,0xb42767f440d39300,0x59ca8a19ad3e7eed,
-0x4f612d034c622e00,0xd3fdb19fd0feb29c,0x4f612d034c622e00,0xd3fdb19fd0feb29c,
-0x9750c90e995ec700,0xf433aa6dfa3da463,0x9750c90e995ec700,0xf433aa6dfa3da463,
-0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4,0x645ffbc0a49f3b00,0xd0eb4f74102b8fb4,
-0x931b951d8e068800,0xd850b831098169e,0x931b951d8e068800,0xd850b831098169e,
-0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c,0x7e50a28cf2dc2e00,0xf2dc2e007e50a28c,
-0xa3548671d225f700,0x2cdb09fe5daa788f,0xa3548671d225f700,0x2cdb09fe5daa788f,
-0x1d41184459055c00,0xc29ec79b86da83df,0x1d41184459055c00,0xc29ec79b86da83df,
-0x7ace1ca8d266b400,0xa511c3770db96bdf,0x7ace1ca8d266b400,0xa511c3770db96bdf,
-0x392d697d44501400,0x8c98dcc8f1e5a1b5,0x392d697d44501400,0x8c98dcc8f1e5a1b5,
-0x6b74554a213e1f00,0x9a85a4bbd0cfeef1,0x6b74554a213e1f00,0x9a85a4bbd0cfeef1,
-0xd0eb073cecd73b00,0xbd866a5181ba566d,0xd0eb073cecd73b00,0xbd866a5181ba566d,
-0xb44c25dd6991f800,0x1ee68f77c33b52aa,0xb44c25dd6991f800,0x1ee68f77c33b52aa,
-0xe65a338f69d5bc00,0x942841fd1ba7ce72,0xe65a338f69d5bc00,0x942841fd1ba7ce72,
-0xe32c8f40a36ccf00,0xa966c50ae926854a,0xe32c8f40a36ccf00,0xa966c50ae926854a,
-0x1fa2813c239ebd00,0x84391aa7b805269b,0x1fa2813c239ebd00,0x84391aa7b805269b,
-0x83ddfca2217f5e00,0xffa180de5d03227c,0x83ddfca2217f5e00,0xffa180de5d03227c,
-0x486c0521694d2400,0x76523b1f57731a3e,0x486c0521694d2400,0x76523b1f57731a3e,
-0xb37b3af24189c800,0xc20a4b8330f8b971,0xb37b3af24189c800,0xc20a4b8330f8b971,
-0xd5a0205580f57500,0x2055d5a0750080f5,0xd5a0205580f57500,0x2055d5a0750080f5,
-0xebef84806b6f0400,0xeeea81856e6a0105,0xebef84806b6f0400,0xeeea81856e6a0105,
-0xef2033fc13dccf00,0xcf0013dc33fcef20,0xef2033fc13dccf00,0xcf0013dc33fcef20,
-0x3f983493ac0ba700,0xac0ba7003f983493,0x3f983493ac0ba700,0xac0ba7003f983493,
-0x29483c5d74156100,0xd0b1c5a48dec98f9,0x29483c5d74156100,0xd0b1c5a48dec98f9,
-0xfbc34b7388b03800,0xf8c048708bb33b03,0xfbc34b7388b03800,0xf8c048708bb33b03,
-0x86d8b6e86e305e00,0x732d431d9bc5abf5,0x86d8b6e86e305e00,0x732d431d9bc5abf5,
-0x6626014127674000,0xc484a3e385c5e2a2,0x6626014127674000,0xc484a3e385c5e2a2,
-0x37cea0596e97f900,0x6b92fc0532cba55c,0x37cea0596e97f900,0x6b92fc0532cba55c,
-0x1bbc73d4cf68a700,0xff5897302b8c43e4,0x1bbc73d4cf68a700,0xff5897302b8c43e4,
-0x3ca6e27844de9a00,0xf95d14b77eda933,0x3ca6e27844de9a00,0xf95d14b77eda933,
-0x1da2e25d40ffbf00,0xdc63239c813e7ec1,0x1da2e25d40ffbf00,0xdc63239c813e7ec1,
-0x3ebcde5c62e08200,0x47c5a7251b99fb79,0x3ebcde5c62e08200,0x47c5a7251b99fb79,
-0x6110cbbadbaa7100,0xbbca11600170abda,0x6110cbbadbaa7100,0xbbca11600170abda,
-0x53fead0d5ef3a00,0xbe84516b6e5481bb,0x53fead0d5ef3a00,0xbe84516b6e5481bb,
-0x5ac17fe4be259b00,0x33a8168dd74cf269,0x5ac17fe4be259b00,0x33a8168dd74cf269,
-0x873ec47dfa43b900,0x62db21981fa65ce5,0x873ec47dfa43b900,0x62db21981fa65ce5,
-0xad2b4fc964e28600,0xc14723a5088eea6c,0xad2b4fc964e28600,0xc14723a5088eea6c,
-0xdda5ceb66b137800,0x463e552df088e39b,0xdda5ceb66b137800,0x463e552df088e39b,
-0x5c349ef6aac26800,0x1a72d8b0ec842e46,0x5c349ef6aac26800,0x1a72d8b0ec842e46,
-0xca96e3bf75295c00,0x4a16633ff5a9dc80,0xca96e3bf75295c00,0x4a16633ff5a9dc80,
-0xc26ecc6cae02a00,0x3319d3f9f5df153f,0xc26ecc6cae02a00,0x3319d3f9f5df153f,
-0xf9d55e728ba72c00,0xc5e9624eb79b103c,0xf9d55e728ba72c00,0xc5e9624eb79b103c,
-0x42bdd12e6c93ff00,0xe31c708fcd325ea1,0x42bdd12e6c93ff00,0xe31c708fcd325ea1,
-0xb594ba9b2e0f2100,0x31103e1faa8ba584,0xb594ba9b2e0f2100,0x31103e1faa8ba584,
-0xfd6b3bad50c69600,0xc9aca5ca13767f1,0xfd6b3bad50c69600,0xc9aca5ca13767f1,
-0xe3a77034d7934400,0xade93e7a99dd0a4e,0xe3a77034d7934400,0xade93e7a99dd0a4e,
-0x48763709417f3e00,0x3d03427c340a4b75,0x48763709417f3e00,0x3d03427c340a4b75,
-0x2228c8c2e0ea0a00,0x868c6c66444eaea4,0x2228c8c2e0ea0a00,0x868c6c66444eaea4,
-0x9cfff4970b686300,0x23404b28b4d7dcbf,0x9cfff4970b686300,0x23404b28b4d7dcbf,
-0xdc65ef568a33b900,0xe75ed46db108823b,0xdc65ef568a33b900,0xe75ed46db108823b,
-0x3867e7b880df5f00,0x732cacf3cb94144b,0x3867e7b880df5f00,0x732cacf3cb94144b,
-0x963f7fd640e9a900,0x359cdc75e34a0aa3,0x963f7fd640e9a900,0x359cdc75e34a0aa3,
-0x31b58f0b3abe8400,0xdf5b61e5d4506aee,0x31b58f0b3abe8400,0xdf5b61e5d4506aee,
-0xea316fb45e85db00,0xa8732df61cc79942,0xea316fb45e85db00,0xa8732df61cc79942,
-0xb5b54949fcfc0000,0x747488883d3dc1c1,0xb5b54949fcfc0000,0x747488883d3dc1c1,
-0x43d2910142d3900,0xedd4c0f9fdc4d0e9,0x43d2910142d3900,0xedd4c0f9fdc4d0e9,
-0xb31ea508bb16ad00,0x76db60cd7ed368c5,0xb31ea508bb16ad00,0x76db60cd7ed368c5,
-0xf6822e5aacd87400,0x1460ccb84e3a96e2,0xf6822e5aacd87400,0x1460ccb84e3a96e2,
-0xa78ae9c4634e2d00,0xe8c5a68b2c01624f,0xa78ae9c4634e2d00,0xe8c5a68b2c01624f,
-0x1dabcf7964d2b600,0xfd4b2f99843256e0,0x1dabcf7964d2b600,0xfd4b2f99843256e0,
-0xa315e452f147b600,0x259362d477c13086,0xa315e452f147b600,0x259362d477c13086,
-0x81d27320a1f25300,0x491abbe8693a9bc8,0x81d27320a1f25300,0x491abbe8693a9bc8,
-0xe7268b4aad6cc100,0x21e04d8c6baa07c6,0xe7268b4aad6cc100,0x21e04d8c6baa07c6,
-0x5a4e44540e1a100,0x2786c66762c38322,0x5a4e44540e1a100,0x2786c66762c38322,
-0x5d98b6732eebc500,0xe32608cd90557bbe,0x5d98b6732eebc500,0xe32608cd90557bbe,
-0x91943732a3a60500,0xc4c16267f6f35055,0x91943732a3a60500,0xc4c16267f6f35055,
-0x3e9008a69836ae00,0x5cf26ac4fa54cc62,0x3e9008a69836ae00,0x5cf26ac4fa54cc62,
-0x1f94d9524dc68b00,0xe9622fa4bb307df6,0x1f94d9524dc68b00,0xe9622fa4bb307df6,
-0xedbb1640adfb5600,0x194fe2b4590fa2f4,0xedbb1640adfb5600,0x194fe2b4590fa2f4,
-0x1836745a426c2e00,0xfed092bca48ac8e6,0x1836745a426c2e00,0xfed092bca48ac8e6,
-0xb7110dab1cbaa600,0x5ef8e442f5534fe9,0xb7110dab1cbaa600,0x5ef8e442f5534fe9,
-0x6347c2e685a12400,0xc8ec694d2e0a8fab,0x6347c2e685a12400,0xc8ec694d2e0a8fab,
-0xf3d59fb94a6c2600,0x89afe5c330165c7a,0xf3d59fb94a6c2600,0x89afe5c330165c7a,
-0xa5053c9c3999a000,0x4dedd474d17148e8,0xa5053c9c3999a000,0x4dedd474d17148e8,
-0xef21f43ad51bce00,0xc50bde10ff31e42a,0xef21f43ad51bce00,0xc50bde10ff31e42a,
-0x6263626301000100,0x585958593b3a3b3a,0x6263626301000100,0x585958593b3a3b3a,
-0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6,0xf9e4c6db223f1d00,0x1f02203dc4d9fbe6,
-0xfe067f877981f800,0x1ae29b639d651ce4,0xfe067f877981f800,0x1ae29b639d651ce4,
-0xfb35e22cd719ce00,0xee20f739c20cdb15,0xfb35e22cd719ce00,0xee20f739c20cdb15,
-0xd262da6ab808b000,0x95259d2dff4ff747,0xd262da6ab808b000,0x95259d2dff4ff747,
-0x53c031a2f1629300,0xac3fce5d0e9d6cff,0x53c031a2f1629300,0xac3fce5d0e9d6cff,
-0x5b7bfede85a52000,0x86a623035878fddd,0x5b7bfede85a52000,0x86a623035878fddd,
-0xf9d43518e1cc2d00,0x8fa2436e97ba5b76,0xf9d43518e1cc2d00,0x8fa2436e97ba5b76,
-0x4edc63f1bf2d9200,0x68fa45d7990bb426,0x4edc63f1bf2d9200,0x68fa45d7990bb426,
-0xc964973af35ead00,0x45e81bb67fd2218c,0xc964973af35ead00,0x45e81bb67fd2218c,
-0x6f3d21731c4e5200,0x2f7d61335c0e1240,0x6f3d21731c4e5200,0x2f7d61335c0e1240,
-0x101df7faeae70d00,0x68658f82929f7578,0x101df7faeae70d00,0x68658f82929f7578,
-0x24aaa6280c828e00,0xa9272ba5810f038d,0x24aaa6280c828e00,0xa9272ba5810f038d,
-0xb34652a714e1f500,0x8d786c992adfcb3e,0xb34652a714e1f500,0x8d786c992adfcb3e,
-0x72bb8f4634fdc900,0x3af3c70e7cb58148,0x72bb8f4634fdc900,0x3af3c70e7cb58148,
-0xdff4361dc2e92b00,0xdbf03219c6ed2f04,0xdff4361dc2e92b00,0xdbf03219c6ed2f04,
-0x17e81ee1f609ff00,0x4db244bbac53a55a,0x17e81ee1f609ff00,0x4db244bbac53a55a,
-0xe3492e8467cdaa00,0xc66c0ba142e88f25,0xe3492e8467cdaa00,0xc66c0ba142e88f25,
-0xb062bd6fdf0dd200,0x13c11ecc7cae71a3,0xb062bd6fdf0dd200,0x13c11ecc7cae71a3,
-0xdbb1e68c573d6a00,0x6c06513be08addb7,0xdbb1e68c573d6a00,0x6c06513be08addb7,
-0x754797a5d0e23200,0x586aba88fdcf1f2d,0x754797a5d0e23200,0x586aba88fdcf1f2d,
-0xd5273cce1be9f200,0x83716a984dbfa456,0xd5273cce1be9f200,0x83716a984dbfa456,
-0xa522e767c245800,0x277f035b5109752d,0xa522e767c245800,0x277f035b5109752d,
-0xf302c938cb3af100,0xe415de2fdc2de617,0xf302c938cb3af100,0xe415de2fdc2de617,
-0x7a61d4cfb5ae1b00,0x869d28334952e7fc,0x7a61d4cfb5ae1b00,0x869d28334952e7fc,
-0x9b98797ae1e20300,0x5655b4b72c2fcecd,0x9b98797ae1e20300,0x5655b4b72c2fcecd,
-0x6601462147206700,0x6a0d4a2d4b2c6b0c,0x6601462147206700,0x6a0d4a2d4b2c6b0c,
-0x2e3668705e461800,0x140c524a647c223a,0x2e3668705e461800,0x140c524a647c223a,
-0x3223213002131100,0xeafbf9e8dacbc9d8,0x3223213002131100,0xeafbf9e8dacbc9d8,
-0x617a233859421b00,0x1c075e45243f667d,0x617a233859421b00,0x1c075e45243f667d,
-0x582df085dda87500,0xd1a4790c5421fc89,0x582df085dda87500,0xd1a4790c5421fc89,
-0xce8c3c7eb0f24200,0xf5b707458bc9793b,0xce8c3c7eb0f24200,0xf5b707458bc9793b,
-0x79743d3049440d00,0x808dc4c9b0bdf4f9,0x79743d3049440d00,0x808dc4c9b0bdf4f9,
-0x787edcdaa2a40600,0x5452f0f68e882a2c,0x787edcdaa2a40600,0x5452f0f68e882a2c,
-0xe427e427c300c300,0x93509350b477b477,0xe427e427c300c300,0x93509350b477b477,
-0xe1ab2d6786cc4a00,0xb9f3753fde941258,0xe1ab2d6786cc4a00,0xb9f3753fde941258,
-0x5b63d3ebb0883800,0xad95251d467ecef6,0x5b63d3ebb0883800,0xad95251d467ecef6,
-0xa6aebfb711190800,0x9b93828a2c24353d,0xa6aebfb711190800,0x9b93828a2c24353d,
-0xa84c28cc6480e400,0x42a6c2268e6a0eea,0xa84c28cc6480e400,0x42a6c2268e6a0eea,
-0xfd2827f20fdad500,0xa4717eab56838c59,0xfd2827f20fdad500,0xa4717eab56838c59,
-0xcb68f7549f3ca300,0x5dfe61c209aa3596,0xcb68f7549f3ca300,0x5dfe61c209aa3596,
-0x91fbb8d243296a00,0x9cf6b5df4e24670d,0x91fbb8d243296a00,0x9cf6b5df4e24670d,
-0x89da1546cf9c5300,0x7526e9ba3360affc,0x89da1546cf9c5300,0x7526e9ba3360affc,
-0xe6b22d799fcb5400,0xaafe6135d387184c,0xe6b22d799fcb5400,0xaafe6135d387184c,
-0xd5587dfd28a5800,0xf6ae7c242971a3fb,0xd5587dfd28a5800,0xf6ae7c242971a3fb,
-};
-
-
-uint64_t i_beta_mul_64_bm4r_ext_8 [2*128*4*2] __attribute__((aligned(32))) = {
-0xb8b96a6bd3d20100,0x3e3feced55548786,0xb8b96a6bd3d20100,0x3e3feced55548786,
-0x80a06e4eceee2000,0x4d6da3830323edcd,0x80a06e4eceee2000,0x4d6da3830323edcd,
-0x8484a3a327270000,0xc1c1e6e662624545,0x8484a3a327270000,0xc1c1e6e662624545,
-0x34bf20ab9f148b00,0xf279e66d59d24dc6,0x34bf20ab9f148b00,0xf279e66d59d24dc6,
-0xe0e0cfcf2f2f0000,0x9595baba5a5a7575,0xe0e0cfcf2f2f0000,0x9595baba5a5a7575,
-0xbaf4420cb6f84e00,0x6f2197d9632d9bd5,0xbaf4420cb6f84e00,0x6f2197d9632d9bd5,
-0x9f9f5b5bc4c40000,0x606c2c25d5d9999,0x9f9f5b5bc4c40000,0x606c2c25d5d9999,
-0xc7a2e48146236500,0x82e7a1c403662045,0xc7a2e48146236500,0x82e7a1c403662045,
-0x606434345450000,0x2e2e6b6b6d6d2828,0x606434345450000,0x2e2e6b6b6d6d2828,
-0x5560182d784d3500,0xcbfe86b3e6d3ab9e,0x5560182d784d3500,0xcbfe86b3e6d3ab9e,
-0x48482e2e66660000,0x6767010149492f2f,0x48482e2e66660000,0x6767010149492f2f,
-0x286fd592bafd4700,0xbff842052d6ad097,0x286fd592bafd4700,0xbff842052d6ad097,
-0xc2c23434f6f60000,0x3d3dcbcb0909ffff,0xc2c23434f6f60000,0x3d3dcbcb0909ffff,
-0xc822d03af218ea00,0x4ca654be769c6e84,0xc822d03af218ea00,0x4ca654be769c6e84,
-0x3939d5d5ecec0000,0x66668a8ab3b35f5f,0x3939d5d5ecec0000,0x66668a8ab3b35f5f,
-0x1b858a140f919e00,0x6ff1fe607be5ea74,0x1b858a140f919e00,0x6ff1fe607be5ea74,
-0x7809f687ff8e7100,0xccbd42334b3ac5b4,0x7809f687ff8e7100,0xccbd42334b3ac5b4,
-0xa38f96ba19352c00,0x79554c60c3eff6da,0xa38f96ba19352c00,0x79554c60c3eff6da,
-0x434b2f27646c0800,0xcfc7a3abe8e0848c,0x434b2f27646c0800,0xcfc7a3abe8e0848c,
-0x5d0359075a045e00,0x1648124c114f154b,0x5d0359075a045e00,0x1648124c114f154b,
-0xd1df5e50818f0e00,0x4a44c5cb1a14959b,0xd1df5e50818f0e00,0x4a44c5cb1a14959b,
-0xacdfcab915667300,0x344752218dfeeb98,0xacdfcab915667300,0x344752218dfeeb98,
-0xaf3a15802fba9500,0x1a8fa0359a0f20b5,0xaf3a15802fba9500,0x1a8fa0359a0f20b5,
-0x9531d074e145a400,0x54f011b5208465c1,0x9531d074e145a400,0x54f011b5208465c1,
-0xbe1813b50bada600,0xa50308ae10b6bd1b,0xbe1813b50bada600,0xa50308ae10b6bd1b,
-0x5fd3d9550a868c00,0xbe3238b4eb676de1,0x5fd3d9550a868c00,0xbe3238b4eb676de1,
-0xacd1f58824597d00,0x304d6914b8c5e19c,0xacd1f58824597d00,0x304d6914b8c5e19c,
-0xfd6903976afe9400,0x72e68c18e5711b8f,0xfd6903976afe9400,0x72e68c18e5711b8f,
-0x8e6437dd53b9ea00,0xfe5b65cd2386b81,0x8e6437dd53b9ea00,0xfe5b65cd2386b81,
-0xe52cb970955cc900,0x1fd6438a6fa633fa,0xe52cb970955cc900,0x1fd6438a6fa633fa,
-0x17ad82382f95ba00,0x6cd6f94354eec17b,0x17ad82382f95ba00,0x6cd6f94354eec17b,
-0x30b3cb4878fb8300,0x3ebdc54676f58d0e,0x30b3cb4878fb8300,0x3ebdc54676f58d0e,
-0xc16d0fa362ceac00,0x16bad874b5197bd7,0xc16d0fa362ceac00,0x16bad874b5197bd7,
-0xbfab998d32261400,0xf1b293d8296a4b0,0xbfab998d32261400,0xf1b293d8296a4b0,
-0xc2f02113d1e33200,0xdbe9380ac8fa2b19,0xc2f02113d1e33200,0xdbe9380ac8fa2b19,
-0x5d04fba2ffa65900,0x154cb3eab7ee1148,0x5d04fba2ffa65900,0x154cb3eab7ee1148,
-0xdff8c5e23d1a2700,0x3c1b2601def9c4e3,0xdff8c5e23d1a2700,0x3c1b2601def9c4e3,
-0xbda7e2f8455f1a00,0x455f1a00bda7e2f8,0xbda7e2f8455f1a00,0x455f1a00bda7e2f8,
-0xe632ca1ef82cd400,0x29fd05d137e31bcf,0xe632ca1ef82cd400,0x29fd05d137e31bcf,
-0xe916b04fa659ff00,0x7c8325da33cc6a95,0xe916b04fa659ff00,0x7c8325da33cc6a95,
-0xf4a6ce9c683a5200,0x2270184abeec84d6,0xf4a6ce9c683a5200,0x2270184abeec84d6,
-0xc0b896ee2e567800,0x572f0179b9c1ef97,0xc0b896ee2e567800,0x572f0179b9c1ef97,
-0x2bb962f2d94b900,0x5ce5c87173cae75e,0x2bb962f2d94b900,0x5ce5c87173cae75e,
-0xee7055cb25bb9e00,0x5ec0e57b950b2eb0,0xee7055cb25bb9e00,0x5ec0e57b950b2eb0,
-0xee0a64846a8ee00,0x638dcb252bc5836d,0xee0a64846a8ee00,0x638dcb252bc5836d,
-0x2a483c5e74166200,0x593b4f2d07651173,0x2a483c5e74166200,0x593b4f2d07651173,
-0x49d02eb7fe679900,0x69f00e97de47b920,0x49d02eb7fe679900,0x69f00e97de47b920,
-0x9d978c861b110a00,0x8f859e9409031812,0x9d978c861b110a00,0x8f859e9409031812,
-0xe0d8073fdfe73800,0x6f5788b05068b78f,0xe0d8073fdfe73800,0x6f5788b05068b78f,
-0xe3219052b173c200,0xcd0fbe7c9f5dec2e,0xe3219052b173c200,0xcd0fbe7c9f5dec2e,
-0xf6b5c3837536400,0x593d0a6e61053256,0xf6b5c3837536400,0x593d0a6e61053256,
-0xd34abc25f66f9900,0x6bf2049d4ed721b8,0xd34abc25f66f9900,0x6bf2049d4ed721b8,
-0x8b55ad73f826de00,0x75ab538d06d820fe,0x8b55ad73f826de00,0x75ab538d06d820fe,
-0x4766d9f8bf9e2100,0xe9c8775611308fae,0x4766d9f8bf9e2100,0xe9c8775611308fae,
-0x3cfce2221edec000,0xa66678b884445a9a,0x3cfce2221edec000,0xa66678b884445a9a,
-0xfc51913cc06dad00,0x4de0208d71dc1cb1,0xfc51913cc06dad00,0x4de0208d71dc1cb1,
-0x876524c641a3e200,0xdf3d7c9e19fbba58,0x876524c641a3e200,0xdf3d7c9e19fbba58,
-0x4a8a985812d2c000,0x13d3c1014b8b9959,0x4a8a985812d2c000,0x13d3c1014b8b9959,
-0x5288449ecc16da00,0x23f935efbd67ab71,0x5288449ecc16da00,0x23f935efbd67ab71,
-0x4237126725507500,0x9eebcebbf98ca9dc,0x4237126725507500,0x9eebcebbf98ca9dc,
-0x3fe6954c73aad900,0x4f96e53c03daa970,0x3fe6954c73aad900,0x4f96e53c03daa970,
-0x47cfc64e09818800,0x24aca52d6ae2eb63,0x47cfc64e09818800,0x24aca52d6ae2eb63,
-0xb98b4476cffd3200,0xb587487ac3f13e0c,0xb98b4476cffd3200,0xb587487ac3f13e0c,
-0xe7b90e5eb9e7500,0xccb95227295cb7c2,0xe7b90e5eb9e7500,0xccb95227295cb7c2,
-0x3eff71b08e4fc100,0xe524aa6b55941adb,0x3eff71b08e4fc100,0xe524aa6b55941adb,
-0x476184a2e5c32600,0x99bf5a7c3b1df8de,0x476184a2e5c32600,0x99bf5a7c3b1df8de,
-0x63f89a0162f99b00,0x7ce7851e7de6841f,0x63f89a0162f99b00,0x7ce7851e7de6841f,
-0x4eba1de9a753f400,0x29dd7a8ec0349367,0x4eba1de9a753f400,0x29dd7a8ec0349367,
-0xe25fa914f64bbd00,0xec51a71af845b30e,0xe25fa914f64bbd00,0xec51a71af845b30e,
-0x52f72386d471a500,0x52f72386d471a500,0x52f72386d471a500,0x52f72386d471a500,
-0xf9c4023fc6fb3d00,0xa994526f96ab6d50,0xf9c4023fc6fb3d00,0xa994526f96ab6d50,
-0x925b25ec7eb7c900,0xea235d9406cfb178,0x925b25ec7eb7c900,0xea235d9406cfb178,
-0xbf963e17a8812900,0x755cf4dd624be3ca,0xbf963e17a8812900,0x755cf4dd624be3ca,
-0xe1b1baea0b5b5000,0x45151e4eaffff4a4,0xe1b1baea0b5b5000,0x45151e4eaffff4a4,
-0xaee791d8763f4900,0xa2eb9dd47a33450c,0xaee791d8763f4900,0xa2eb9dd47a33450c,
-0x17a511a3b406b200,0x17a511a3b406b200,0x17a511a3b406b200,0x17a511a3b406b200,
-0x2e6a9edaf4b04400,0xd59165210f4bbffb,0x2e6a9edaf4b04400,0xd59165210f4bbffb,
-0x87972e3eb9a91000,0x3a2a93830414adbd,0x87972e3eb9a91000,0x3a2a93830414adbd,
-0xe1bea0ff1e415f00,0xe4bba5fa1b445a05,0xe1bea0ff1e415f00,0xe4bba5fa1b445a05,
-0x689a7d8fe715f200,0x11e304f69e6c8b79,0x689a7d8fe715f200,0x11e304f69e6c8b79,
-0x4e20e48ac4aa6e00,0xc2ac68064826e28c,0x4e20e48ac4aa6e00,0xc2ac68064826e28c,
-0x91a40633a2973500,0xecd97b4edfea487d,0x91a40633a2973500,0xecd97b4edfea487d,
-0xe8e76b648c830f00,0xeee16d628a850906,0xe8e76b648c830f00,0xeee16d628a850906,
-0x462894fabcd26e00,0x8ce25e307618a4ca,0x462894fabcd26e00,0x8ce25e307618a4ca,
-0x5eddd0530d8e8300,0x82010c8fd1525fdc,0x5eddd0530d8e8300,0x82010c8fd1525fdc,
-0xbbba5e5fe4e50100,0xb0b15554efee0a0b,0xbbba5e5fe4e50100,0xb0b15554efee0a0b,
-0xff4363df209cbc00,0xbb7972bd46848f4,0xff4363df209cbc00,0xbb7972bd46848f4,
-0xe76235b057d28500,0x46c39411f67324a1,0xe76235b057d28500,0x46c39411f67324a1,
-0xfcd589a9557c200,0x589a0fcdc2009557,0xfcd589a9557c200,0x589a0fcdc2009557,
-0xda40cb518b119a00,0x4fd55ec41e840f95,0xda40cb518b119a00,0x4fd55ec41e840f95,
-0xeb7d17816afc9600,0xd84e24b259cfa533,0xeb7d17816afc9600,0xd84e24b259cfa533,
-0x86945e4ccad81200,0x1705cfdd5b498391,0x86945e4ccad81200,0x1705cfdd5b498391,
-0x496093baf3da2900,0x674ebd94ddf4072e,0x496093baf3da2900,0x674ebd94ddf4072e,
-0x43f8259edd66bb00,0x76cd10abe8538e35,0x43f8259edd66bb00,0x76cd10abe8538e35,
-0x82d6194dcf9b5400,0x5c08c79311458ade,0x82d6194dcf9b5400,0x5c08c79311458ade,
-0x2969195970304000,0xedaddd9db4f484c4,0x2969195970304000,0xedaddd9db4f484c4,
-0x886258b23ad0ea00,0x1ebd13bb3596389,0x886258b23ad0ea00,0x1ebd13bb3596389,
-0x2d15b888a59d300,0x13c04a999b48c211,0x2d15b888a59d300,0x13c04a999b48c211,
-0x28759fc2eab75d00,0xda876d301845aff2,0x28759fc2eab75d00,0xda876d301845aff2,
-0x88a8301098b82000,0x2c0c94b43c1c84a4,0x88a8301098b82000,0x2c0c94b43c1c84a4,
-0xa029008929a08900,0x73fad35afa735ad3,0xa029008929a08900,0x73fad35afa735ad3,
-0x6230ebb9db895200,0xa5f72c7e1c4e95c7,0x6230ebb9db895200,0xa5f72c7e1c4e95c7,
-0x4a76407c360a3c00,0xba86b08cc6faccf0,0x4a76407c360a3c00,0xba86b08cc6faccf0,
-0xf9d2ddf60f242b00,0xfad1def50c272803,0xf9d2ddf60f242b00,0xfad1def50c272803,
-0x4d4fd2d29f9d000,0xcdcf52521f1d808,0x4d4fd2d29f9d000,0xcdcf52521f1d808,
-0x82777c890bfef500,0x13e6ed189a6f6491,0x82777c890bfef500,0x13e6ed189a6f6491,
-0x135be8a0b3fb4800,0x99d1622a3971c28a,0x135be8a0b3fb4800,0x99d1622a3971c28a,
-0x35268a99acbf1300,0x5d4ee2f1c4d77b68,0x35268a99acbf1300,0x5d4ee2f1c4d77b68,
-0x881b74e76ffc9300,0x8f1c73e068fb9407,0x881b74e76ffc9300,0x8f1c73e068fb9407,
-0xb6acecf6405a1a00,0xf4eeaeb402185842,0xb6acecf6405a1a00,0xf4eeaeb402185842,
-0x1ad0559f854fca00,0x864cc90319d3569c,0x1ad0559f854fca00,0x864cc90319d3569c,
-0x632dc48ae9a74e00,0x9bd53c72115fb6f8,0x632dc48ae9a74e00,0x9bd53c72115fb6f8,
-0x6d0e4a2944276300,0x563571127f1c583b,0x6d0e4a2944276300,0x563571127f1c583b,
-0x5a2e24540e7a700,0x2b8ccc6b6ec9892e,0x5a2e24540e7a700,0x2b8ccc6b6ec9892e,
-0x9749fe2eb967d00,0x3e43a8d5dca14a37,0x9749fe2eb967d00,0x3e43a8d5dca14a37,
-0x42f53780c275b700,0x18af6dda982fed5a,0x42f53780c275b700,0x18af6dda982fed5a,
-0xef2dea28c705c200,0xa86aad6f80428547,0xef2dea28c705c200,0xa86aad6f80428547,
-0x884007cf478fc800,0x2ae2a56de52d6aa2,0x884007cf478fc800,0x2ae2a56de52d6aa2,
-0x959915198c800c00,0xbbb73b37a2ae222e,0x959915198c800c00,0xbbb73b37a2ae222e,
-0xf0209343b363d000,0xada69b949992afa,0xf0209343b363d000,0xada69b949992afa,
-0x5e9e90500ecec00,0xe90505e9ec0000ec,0x5e9e90500ecec00,0xe90505e9ec0000ec,
-0x9da5350d90a83800,0x774fdfe77a42d2ea,0x9da5350d90a83800,0x774fdfe77a42d2ea,
-0xf45f8328dc77ab00,0x2c875bf004af73d8,0xf45f8328dc77ab00,0x2c875bf004af73d8,
-0x40dd5ac7871a9d00,0x920f881555c84fd2,0x40dd5ac7871a9d00,0x920f881555c84fd2,
-0x35e7855762b0d200,0xcc1e7cae9b492bf9,0x35e7855762b0d200,0xcc1e7cae9b492bf9,
-0xd41beb24f03fcf00,0xae61915e8a45b57a,0xd41beb24f03fcf00,0xae61915e8a45b57a,
-0x424ce5eba9a70e00,0xb3bd141a5856fff1,0x424ce5eba9a70e00,0xb3bd141a5856fff1,
-0xa24630d47692e400,0xf612648022c6b054,0xa24630d47692e400,0xf612648022c6b054,
-0x24d033c7e317f400,0x20d437c3e713f004,0x24d033c7e317f400,0x20d437c3e713f004,
-0x39dad83b02e1e300,0x618280635ab9bb58,0x39dad83b02e1e300,0x618280635ab9bb58,
-0x79b4e12c5598cd00,0x74b9ec215895c00d,0x79b4e12c5598cd00,0x74b9ec215895c00d,
-0x35ddeb0336dee800,0xc62e18f0c52d1bf3,0x35ddeb0336dee800,0xc62e18f0c52d1bf3,
-0x6da45a93fe37c900,0x76bf4188e52cd21b,0x6da45a93fe37c900,0x76bf4188e52cd21b,
-0x7f0438433c477b00,0xa714d3649320e75,0x7f0438433c477b00,0xa714d3649320e75,
-0x6c85ee076b82e900,0x29c0ab422ec7ac45,0x6c85ee076b82e900,0x29c0ab422ec7ac45,
-0x977da74dda30ea00,0x3fd50fe5729842a8,0x977da74dda30ea00,0x3fd50fe5729842a8,
-0x7bcb08b8c373b000,0x6ddd1eaed565a616,0x7bcb08b8c373b000,0x6ddd1eaed565a616,
-0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440,0x8480cfcb4f4b0400,0xc4c08f8b0f0b4440,
-0x3cea5a8cb066d600,0xe73181576bbd0ddb,0x3cea5a8cb066d600,0xe73181576bbd0ddb,
-0x23c5f61033d5e600,0xaf497a9cbf596a8c,0x23c5f61033d5e600,0xaf497a9cbf596a8c,
-0xd10ed40bda05df00,0xc21dc718c916cc13,0xd10ed40bda05df00,0xc21dc718c916cc13,
-0x3922cad1e8f31b00,0x2239d1caf3e8001b,0x3922cad1e8f31b00,0x2239d1caf3e8001b,
-0x71a2835322f1d00,0xa3be8c91968bb9a4,0x71a2835322f1d00,0xa3be8c91968bb9a4,
-0x7907403e47397e00,0xd0aee997ee90d7a9,0x7907403e47397e00,0xd0aee997ee90d7a9,
-0x6ba2ae670cc5c900,0x34fdf138539a965f,0x6ba2ae670cc5c900,0x34fdf138539a965f,
-0x34a18e1b2fba9500,0x42d7f86d59cce376,0x34a18e1b2fba9500,0x42d7f86d59cce376,
-0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171,0x36b6ba3a0c8c8000,0x47c7cb4b7dfdf171,
-0xa4d61b69cdbf7200,0x7d0fc2b01466abd9,0xa4d61b69cdbf7200,0x7d0fc2b01466abd9,
-0x83b92d1794ae3a00,0x9ea4300a89b3271d,0x83b92d1794ae3a00,0x9ea4300a89b3271d,
-0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc,0x6ecc8d2f41e3a200,0xa20041e38d2f6ecc,
-0xf672fe7a8c088400,0x5ade52d620a428ac,0xf672fe7a8c088400,0x5ade52d620a428ac,
-0xc7785fe02798bf00,0x229dba05c27d5ae5,0xc7785fe02798bf00,0x229dba05c27d5ae5,
-0xbccbadda66117700,0x33442255e99ef88f,0xbccbadda66117700,0x33442255e99ef88f,
-0xec23d817fb34cf00,0xb9768d42ae619a55,0xec23d817fb34cf00,0xb9768d42ae619a55,
-0xf0095aa353aaf900,0x20d98a73837a29d0,0xf0095aa353aaf900,0x20d98a73837a29d0,
-0xb25329c87a9be100,0x7190ea0bb95822c3,0xb25329c87a9be100,0x7190ea0bb95822c3,
-0x5a963ff3a965cc00,0x7cb62aef438915d,0x5a963ff3a965cc00,0x7cb62aef438915d,
-0xe6d57d4ea89b3300,0x15268ebd5b68c0f3,0xe6d57d4ea89b3300,0x15268ebd5b68c0f3,
-0xe4c02404e0c4200,0x67256b2927652b69,0xe4c02404e0c4200,0x67256b2927652b69,
-0x9ef81177e98f6600,0xa2c42d4bd5b35a3c,0x9ef81177e98f6600,0xa2c42d4bd5b35a3c,
-0x21628fccedae4300,0x682bc685a4e70a49,0x21628fccedae4300,0x682bc685a4e70a49,
-0x97a399ad3a0e3400,0xdaeed4e07743794d,0x97a399ad3a0e3400,0xdaeed4e07743794d,
-0x3147f385b4c27600,0xd4a21660512793e5,0x3147f385b4c27600,0xd4a21660512793e5,
-0xf86d45d028bd9500,0x93062ebb43d6fe6b,0xf86d45d028bd9500,0x93062ebb43d6fe6b,
-0xa8f392c9613a5b00,0xb8e382d9712a4b10,0xa8f392c9613a5b00,0xb8e382d9712a4b10,
-0x7cf854d0ac288400,0xb135991d61e549cd,0x7cf854d0ac288400,0xb135991d61e549cd,
-0x95b8ad8015382d00,0xfed3c6eb7e53466b,0x95b8ad8015382d00,0xfed3c6eb7e53466b,
-0xac9f88bb17243300,0xbc8f98ab07342310,0xac9f88bb17243300,0xbc8f98ab07342310,
-0xe30920ca29c3ea00,0xec062fc526cce50f,0xe30920ca29c3ea00,0xec062fc526cce50f,
-0xf3d1f5d724062200,0x33113517e4c6e2c0,0xf3d1f5d724062200,0x33113517e4c6e2c0,
-0xc5ab523cf9976e00,0x9af40d63a6c8315f,0xc5ab523cf9976e00,0x9af40d63a6c8315f,
-0x3c5c84e4d8b86000,0x3e5e86e6daba6202,0x3c5c84e4d8b86000,0x3e5e86e6daba6202,
-0xe0207cbc5c9cc000,0xe92975b55595c909,0xe0207cbc5c9cc000,0xe92975b55595c909,
-0xc3a5355390f66600,0xf89e0e68abcd5d3b,0xc3a5355390f66600,0xf89e0e68abcd5d3b,
-0x92ab5168fac33900,0x3b02f8c1536a90a9,0x92ab5168fac33900,0x3b02f8c1536a90a9,
-0xb7014cfa4dfbb600,0x15a3ee58ef5914a2,0xb7014cfa4dfbb600,0x15a3ee58ef5914a2,
-0xf268ab31c3599a00,0xab31f2689a00c359,0xf268ab31c3599a00,0xab31f2689a00c359,
-0xe17f76e809979e00,0xb72920be5fc1c856,0xe17f76e809979e00,0xb72920be5fc1c856,
-0x3f76f9b08fc64900,0xfdb43b724d048bc2,0x3f76f9b08fc64900,0xfdb43b724d048bc2,
-0x31289c85b4ad1900,0xa8b1051c2d348099,0x31289c85b4ad1900,0xa8b1051c2d348099,
-0xa75e3bc2659cf900,0x6e97f20bac5530c9,0xa75e3bc2659cf900,0x6e97f20bac5530c9,
-0x222c414f6d630e00,0x6b650806242a4749,0x222c414f6d630e00,0x6b650806242a4749,
-0x52deb23e6ce08c00,0x800c60ecbe325ed2,0x52deb23e6ce08c00,0x800c60ecbe325ed2,
-0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab,0x414cfcf1b0bd0d00,0xeae7575a1b16a6ab,
-0x8bb589b73c023e00,0x19271b25ae90ac92,0x8bb589b73c023e00,0x19271b25ae90ac92,
-0x764a9cacdae6300,0x566abc8cfac6102,0x764a9cacdae6300,0x566abc8cfac6102,
-0x81bdab97162a3c00,0x201c0a36b78b9da1,0x81bdab97162a3c00,0x201c0a36b78b9da1,
-0x8a3d992ea413b700,0x6add79ce44f357e0,0x8a3d992ea413b700,0x6add79ce44f357e0,
-0xbab43c3288860e00,0xfaf47c72c8c64e40,0xbab43c3288860e00,0xfaf47c72c8c64e40,
-0x33917edcef4da200,0x1ebc53f1c2608f2d,0x33917edcef4da200,0x1ebc53f1c2608f2d,
-0x29efdc1a33f5c600,0x4482b1775e98ab6d,0x29efdc1a33f5c600,0x4482b1775e98ab6d,
-0xe17e0e9170ef9f00,0x3da2d24dac3343dc,0xe17e0e9170ef9f00,0x3da2d24dac3343dc,
-0xa7bbffe344581c00,0xd2ce8a96312d6975,0xa7bbffe344581c00,0xd2ce8a96312d6975,
-0x1ca004b8a418bc00,0xbf03a71b07bb1fa3,0x1ca004b8a418bc00,0xbf03a71b07bb1fa3,
-0x7e66948cf2ea1800,0x948c7e661800f2ea,0x7e66948cf2ea1800,0x948c7e661800f2ea,
-0x224ca2ccee806e00,0x355bb5dbf9977917,0x224ca2ccee806e00,0x355bb5dbf9977917,
-0x4c52405e120c1e00,0xb1afbda3eff1e3fd,0x4c52405e120c1e00,0xb1afbda3eff1e3fd,
-0x80ec563abad66c00,0xb8d46e0282ee5438,0x80ec563abad66c00,0xb8d46e0282ee5438,
-0xeeb3d588663b5d00,0x64395f02ecb1d78a,0xeeb3d588663b5d00,0x64395f02ecb1d78a,
-0x53dfb73b68e48c00,0x64e8800c5fd3bb37,0x53dfb73b68e48c00,0x64e8800c5fd3bb37,
-0xfc5059f509a5ac00,0x3a969f33cf636ac6,0xfc5059f509a5ac00,0x3a969f33cf636ac6,
-0xcbd02932f9e21b00,0x51ee7fc372cd5ce,0xcbd02932f9e21b00,0x51ee7fc372cd5ce,
-0x5ba640bde61bfd00,0x9a67817c27da3cc1,0x5ba640bde61bfd00,0x9a67817c27da3cc1,
-0x565d8d86d0db0b00,0x565d8d86d0db0b00,0x565d8d86d0db0b00,0x565d8d86d0db0b00,
-0x8696afbf39291000,0x4f5f6676f0e0d9c9,0x8696afbf39291000,0x4f5f6676f0e0d9c9,
-0x916fc33dac52fe00,0xe51bb749d8268a74,0x916fc33dac52fe00,0xe51bb749d8268a74,
-0x92d47a3caee84600,0xda9c3274e6a00e48,0x92d47a3caee84600,0xda9c3274e6a00e48,
-0x26e9549bbd72cf00,0x1ed16ca3854af738,0x26e9549bbd72cf00,0x1ed16ca3854af738,
-0x32cb27deec15f900,0xaa53bf46748d6198,0x32cb27deec15f900,0xaa53bf46748d6198,
-0xcdb3e39d502e7e00,0xe896c6b8750b5b25,0xcdb3e39d502e7e00,0xe896c6b8750b5b25,
-0xc999bded24745000,0x21715505cc9cb8e8,0xc999bded24745000,0x21715505cc9cb8e8,
-0x280c6b4f67432400,0x795d3a1e36127551,0x280c6b4f67432400,0x795d3a1e36127551,
-0xd0ca859f4f551a00,0xf155a40908ac5df,0xd0ca859f4f551a00,0xf155a40908ac5df,
-0x5167d6e0b1873600,0x94a213257442f3c5,0x5167d6e0b1873600,0x94a213257442f3c5,
-0x43defd6d2eb3900,0xe0d90b32360fdde4,0x43defd6d2eb3900,0xe0d90b32360fdde4,
-0x417f98a6e7d93e00,0x13fd8e6a7997e40,0x417f98a6e7d93e00,0x13fd8e6a7997e40,
-0x34e96eb3875add00,0x20fd7aa7934ec914,0x34e96eb3875add00,0x20fd7aa7934ec914,
-0xaaa2464ee4ec0800,0x535bbfb71d15f1f9,0xaaa2464ee4ec0800,0x535bbfb71d15f1f9,
-0xf2a07725d7855200,0x7022f5a75507d082,0xf2a07725d7855200,0x7022f5a75507d082,
-0x89b34b71f8c23a00,0x7e44bc860f35cdf7,0x89b34b71f8c23a00,0x7e44bc860f35cdf7,
-0x47b6e11057a6f100,0xe71641b0f70651a0,0x47b6e11057a6f100,0xe71641b0f70651a0,
-0x1bc7fe2239e5dc00,0xb76b528e954970ac,0x1bc7fe2239e5dc00,0xb76b528e954970ac,
-0x5488db07538fdc00,0xe23e6db1e5396ab6,0x5488db07538fdc00,0xe23e6db1e5396ab6,
-0xf22c588674aade00,0xd80672ac5e80f42a,0xf22c588674aade00,0xd80672ac5e80f42a,
-0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2,0x6e1ccdbfd1a37200,0x8cfe2f5d334190e2,
-0xde2ac430ee1af400,0x2f618ec32c628dc,0xde2ac430ee1af400,0x2f618ec32c628dc,
-0x3a0b8bba80b13100,0xf4c545744e7fffce,0x3a0b8bba80b13100,0xf4c545744e7fffce,
-0x2cdb1cebc730f700,0x9265a255798e49be,0x2cdb1cebc730f700,0x9265a255798e49be,
-0x56141d5f094b4200,0xf6b4bdffa9ebe2a0,0x56141d5f094b4200,0xf6b4bdffa9ebe2a0,
-0xb7ac455ee9f21b00,0xe7fc150eb9a24b50,0xb7ac455ee9f21b00,0xe7fc150eb9a24b50,
-0x968ad8c4524e1c00,0x21e4c50c6da8894,0x968ad8c4524e1c00,0x21e4c50c6da8894,
-0x1ddacc0b16d1c700,0x2cebfd3a27e0f631,0x1ddacc0b16d1c700,0x2cebfd3a27e0f631,
-0x28539be0c8b37b00,0x99e22a517902cab1,0x28539be0c8b37b00,0x99e22a517902cab1,
-0xc38281c003424100,0x91d0d39251101352,0xc38281c003424100,0x91d0d39251101352,
-0x8681beb93f380700,0xbeb9868107003f38,0x8681beb93f380700,0xbeb9868107003f38,
-0xefd77b43ac943800,0x122a86be5169c5fd,0xefd77b43ac943800,0x122a86be5169c5fd,
-0x9ec67e26b8e05800,0x366ed68e1048f0a8,0x9ec67e26b8e05800,0x366ed68e1048f0a8,
-0x875fed35b26ad800,0x71a91bc3449c2ef6,0x875fed35b26ad800,0x71a91bc3449c2ef6,
-0x2bc23ad3f811e900,0x78916980ab42ba53,0x2bc23ad3f811e900,0x78916980ab42ba53,
-0x2211417250633300,0xf0c393a082b1e1d2,0x2211417250633300,0xf0c393a082b1e1d2,
-0x6966303f56590f00,0xefe0b6b9d0df8986,0x6966303f56590f00,0xefe0b6b9d0df8986,
-0x1d93850b16988e00,0x38d9b150886901e,0x1d93850b16988e00,0x38d9b150886901e,
-0x6b48b497fcdf2300,0x81a25e7d1635c9ea,0x6b48b497fcdf2300,0x81a25e7d1635c9ea,
-0x40094a03430a4900,0xde97d49ddd94d79e,0x40094a03430a4900,0xde97d49ddd94d79e,
-0x74019aef9bee7500,0x4b3ea5d0a4d14a3f,0x74019aef9bee7500,0x4b3ea5d0a4d14a3f,
-0x36691c43752a5f00,0x2f70055a6c334619,0x36691c43752a5f00,0x2f70055a6c334619,
-0xbba91507bcae1200,0xcfdd6173c8da6674,0xbba91507bcae1200,0xcfdd6173c8da6674,
-0x2980993910b9a00,0xa90019b99039208,0x2980993910b9a00,0xa90019b99039208,
-0xfc3bb0778b4cc700,0xac6be027db1c9750,0xfc3bb0778b4cc700,0xac6be027db1c9750,
-0x70ed1f82f26f9d00,0x118c7ee3930efc61,0x70ed1f82f26f9d00,0x118c7ee3930efc61,
-0x8c5ac7119d4bd600,0xeb3da076fa2cb167,0x8c5ac7119d4bd600,0xeb3da076fa2cb167,
-0x8a18fe6ce6749200,0x9a08ee7cf6648210,0x8a18fe6ce6749200,0x9a08ee7cf6648210,
-0xfa5b48e913b2a100,0x75d4c7669c3d2e8f,0xfa5b48e913b2a100,0x75d4c7669c3d2e8f,
-0x6d660d066b600b00,0xd066d660b006b60,0x6d660d066b600b00,0xd066d660b006b60,
-0xc5c16763a6a20400,0xa8ac0a0ecbcf696d,0xc5c16763a6a20400,0xa8ac0a0ecbcf696d,
-0x1b48f2a1bae95300,0x4112a8fbe0b3095a,0x1b48f2a1bae95300,0x4112a8fbe0b3095a,
-0xcaca47478d8d0000,0x5c5cd1d11b1b9696,0xcaca47478d8d0000,0x5c5cd1d11b1b9696,
-0x56ac83792fd5fa00,0x976d42b8ee143bc1,0x56ac83792fd5fa00,0x976d42b8ee143bc1,
-0x9f9febeb74740000,0x13136767f8f88c8c,0x9f9febeb74740000,0x13136767f8f88c8c,
-0x13dbfd3526eec800,0x5098be7665ad8b43,0x13dbfd3526eec800,0x5098be7665ad8b43,
-0x65659f9ffafa0000,0x5252a8a8cdcd3737,0x65659f9ffafa0000,0x5252a8a8cdcd3737,
-0x96bf8da4321b2900,0x153c0e27b198aa83,0x96bf8da4321b2900,0x153c0e27b198aa83,
-0xf1f10909f8f80000,0x5656aeae5f5fa7a7,0xf1f10909f8f80000,0x5656aeae5f5fa7a7,
-0xf4d29bbd496f2600,0x2246d4bbf99d0f6,0xf4d29bbd496f2600,0x2246d4bbf99d0f6,
-0x3d3d0a0a37370000,0xe7e7d0d0ededdada,0x3d3d0a0a37370000,0xe7e7d0d0ededdada,
-0x1e4a8bdfc1955400,0xf4a061352b7fbeea,0x1e4a8bdfc1955400,0xf4a061352b7fbeea,
-0x1e1e565648480000,0x4c4c04041a1a5252,0x1e1e565648480000,0x4c4c04041a1a5252,
-0x5fbe36d78869e100,0xf5149c7d22c34baa,0x5fbe36d78869e100,0xf5149c7d22c34baa,
-0x7373efef9c9c0000,0x8f8f13136060fcfc,0x7373efef9c9c0000,0x8f8f13136060fcfc,
-0x1fe840b7a85ff700,0x4f35bacb344ec1b,0x1fe840b7a85ff700,0x4f35bacb344ec1b,
-0x6666ddddbbbb0000,0x6969d2d2b4b40f0f,0x6666ddddbbbb0000,0x6969d2d2b4b40f0f,
-0x423fa1dc9ee37d00,0x5e23bdc082ff611c,0x423fa1dc9ee37d00,0x5e23bdc082ff611c,
-0xca4b1b9a50d18100,0x1c9dcd4c860757d6,0xca4b1b9a50d18100,0x1c9dcd4c860757d6,
-0xba8993a3192a300,0xb81b2a89822110b3,0xba8993a3192a300,0xb81b2a89822110b3,
-0xa5ce99f2573c6b00,0xa8c394ff5a31660d,0xa5ce99f2573c6b00,0xa8c394ff5a31660d,
-0xab2831b2199a8300,0x5fdcc546ed6e77f4,0xab2831b2199a8300,0x5fdcc546ed6e77f4,
-0xf607a958ae5ff100,0xc83997669061cf3e,0xf607a958ae5ff100,0xc83997669061cf3e,
-0xa531fa6ecb5f9400,0x9b0fc450f561aa3e,0xa531fa6ecb5f9400,0x9b0fc450f561aa3e,
-0x7f39afe996d04600,0x9cda4c0a7533a5e3,0x7f39afe996d04600,0x9cda4c0a7533a5e3,
-0x7d1588e09df56800,0x86ee731b660e93fb,0x7d1588e09df56800,0x86ee731b660e93fb,
-0x52013f6c3e6d5300,0xaffcc291c390aefd,0x52013f6c3e6d5300,0xaffcc291c390aefd,
-0x488c79bdf531c400,0xdf1bee2a62a65397,0x488c79bdf531c400,0xdf1bee2a62a65397,
-0xd7a77303d4a47000,0xd2a27606d1a17505,0xd7a77303d4a47000,0xd2a27606d1a17505,
-0xb7ff7e3681c94800,0x145cdd95226aeba3,0xb7ff7e3681c94800,0x145cdd95226aeba3,
-0x6399c03a59a3fa00,0xd72d748eed174eb4,0x6399c03a59a3fa00,0xd72d748eed174eb4,
-0xd7ceb1a87f661900,0xf1e8978e59403f26,0xd7ceb1a87f661900,0xf1e8978e59403f26,
-0x5f3e98f9a6c76100,0x86e741207f1eb8d9,0x5f3e98f9a6c76100,0x86e741207f1eb8d9,
-0xcc31af529e63fd00,0x6c910ff23ec35da0,0xcc31af529e63fd00,0x6c910ff23ec35da0,
-0xe6a1b3f412554700,0xabecfeb95f180a4d,0xe6a1b3f412554700,0xabecfeb95f180a4d,
-0x37012f192e183600,0x6157794f784e6056,0x37012f192e183600,0x6157794f784e6056,
-0x286eca8ca4e24600,0x4600a4e2ca8c286e,0x286eca8ca4e24600,0x4600a4e2ca8c286e,
-0xca68f2509a38a200,0x8e2cb614de7ce644,0xca68f2509a38a200,0x8e2cb614de7ce644,
-0x5db2ee015cb3ef00,0xbc530fe0bd520ee1,0x5db2ee015cb3ef00,0xbc530fe0bd520ee1,
-0xf92f00d62ff9d600,0x15c3ec3ac3153aec,0xf92f00d62ff9d600,0x15c3ec3ac3153aec,
-0xb25147a416f5e300,0xf41701e250b3a546,0xb25147a416f5e300,0xf41701e250b3a546,
-0x9dbd22029fbf2000,0xad8d1232af8f1030,0x9dbd22029fbf2000,0xad8d1232af8f1030,
-0x4ce911b4f85da500,0x3f9a62c78b2ed673,0x4ce911b4f85da500,0x3f9a62c78b2ed673,
-0xf9ca6556af9c3300,0xc6f55a6990a30c3f,0xf9ca6556af9c3300,0xc6f55a6990a30c3f,
-0x4e9865b3fd2bd600,0xc412ef3977a15c8a,0x4e9865b3fd2bd600,0xc412ef3977a15c8a,
-0x4677625315243100,0xf0c1d4e5a39287b6,0x4677625315243100,0xf0c1d4e5a39287b6,
-0x2e601d537d334e00,0x86c8b5fbd59be6a8,0x2e601d537d334e00,0x86c8b5fbd59be6a8,
-0x44c455d591118000,0x890998185cdc4dcd,0x44c455d591118000,0x890998185cdc4dcd,
-0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4,0x3e1d6447795a2300,0x9ab9c0e3ddfe87a4,
-0x2167561031774600,0x442733514526325,0x2167561031774600,0x442733514526325,
-0xf371078576f48200,0xe8cfa788b097ffd,0xf371078576f48200,0xe8cfa788b097ffd,
-0xa719912f8836be00,0x843ab20cab159d23,0xa719912f8836be00,0x843ab20cab159d23,
-0x89c5115dd4984c00,0xb5f92d61e8a4703c,0x89c5115dd4984c00,0xb5f92d61e8a4703c,
-0x50cce47828b49c00,0xd44860fcac301884,0x50cce47828b49c00,0xd44860fcac301884,
-0xa1b1869637271000,0xefffc8d879695e4e,0xa1b1869637271000,0xefffc8d879695e4e,
-0x1f3b391d02262400,0x4c686a4e51757753,0x1f3b391d02262400,0x4c686a4e51757753,
-0x3237fbfeccc90500,0xbcb9757042478b8e,0x3237fbfeccc90500,0xbcb9757042478b8e,
-0x6077d7c7a7b0100,0x2d2c565751502a2b,0x6077d7c7a7b0100,0x2d2c565751502a2b,
-0x2e268f87a9a10800,0xfff75e567870d9d1,0x2e268f87a9a10800,0xfff75e567870d9d1,
-0x73212e7c0f5d5200,0x72202f7d0e5c5301,0x73212e7c0f5d5200,0x72202f7d0e5c5301,
-0x458d38f0b57dc800,0x9951e42c69a114dc,0x458d38f0b57dc800,0x9951e42c69a114dc,
-0x7b0bc7b7ccbc7000,0x373bfcfb4c40878,0x7b0bc7b7ccbc7000,0x373bfcfb4c40878,
-0x4b148fdf94cb500,0x299c65d0d461982d,0x4b148fdf94cb500,0x299c65d0d461982d,
-0xd591145481c5400,0xfbafe7b3beeaa2f6,0xd591145481c5400,0xfbafe7b3beeaa2f6,
-0xc32aa34a8960e900,0xc32aa34a8960e900,0xc32aa34a8960e900,0xc32aa34a8960e900,
-0x235ab6cfec957900,0x4b32dea784fd1168,0x235ab6cfec957900,0x4b32dea784fd1168,
-0xe30eb558bb56ed00,0x43ae15f81bf64da0,0xe30eb558bb56ed00,0x43ae15f81bf64da0,
-0x5ddffa7825a78200,0xf67451d38e0c29ab,0x5ddffa7825a78200,0xf67451d38e0c29ab,
-0x9b96dad74c410d00,0xd004c41dad79b96,0x9b96dad74c410d00,0xd004c41dad79b96,
-0xf0965432c2a46600,0x4e28ea8c7c1ad8be,0xf0965432c2a46600,0x4e28ea8c7c1ad8be,
-0xfcb5b1f8044d4900,0x95dcd8916d242069,0xfcb5b1f8044d4900,0x95dcd8916d242069,
-0x5d24ef96cbb27900,0xa8d11a633e478cf5,0x5d24ef96cbb27900,0xa8d11a633e478cf5,
-0xfae6839f65791c00,0x504c2935cfd3b6aa,0xfae6839f65791c00,0x504c2935cfd3b6aa,
-0xab0ef257fc59a500,0x4aef13b61db844e1,0xab0ef257fc59a500,0x4aef13b61db844e1,
-0x12bd3f90822daf00,0xe946c46b79d654fb,0x12bd3f90822daf00,0xe946c46b79d654fb,
-0x4dbe23d39e6df00,0xf62910cfcb142df2,0x4dbe23d39e6df00,0xf62910cfcb142df2,
-0xe3abb8f81b53400,0x6d59d8ece2d65763,0xe3abb8f81b53400,0x6d59d8ece2d65763,
-0xeaf6f9e50f131c00,0x839f908c667a7569,0xeaf6f9e50f131c00,0x839f908c667a7569,
-0xe171f06081119000,0x4ada5bcb2aba3bab,0xe171f06081119000,0x4ada5bcb2aba3bab,
-0x9d95838b161e0800,0x848c9a920f071119,0x9d95838b161e0800,0x848c9a920f071119,
-0xbc5e24c67a98e200,0xd4364cae12f08a68,0xbc5e24c67a98e200,0xd4364cae12f08a68,
-0x2e7833654b1d5600,0x30662d7b5503481e,0x2e7833654b1d5600,0x30662d7b5503481e,
-0xf9e1e0f801191800,0xa9b1b0a851494850,0xf9e1e0f801191800,0xa9b1b0a851494850,
-0x6177b6a6c7d1100,0xeffe92838594f8e9,0x6177b6a6c7d1100,0xeffe92838594f8e9,
-0x6bf9a93b50c29200,0x8c1e4edcb72575e7,0x6bf9a93b50c29200,0x8c1e4edcb72575e7,
-0x7ed997304ee9a700,0x3b9cd2750bace245,0x7ed997304ee9a700,0x3b9cd2750bace245,
-0x58bf1bfca443e700,0x9f78dc3b638420c7,0x58bf1bfca443e700,0x9f78dc3b638420c7,
-0x13ea34cdde27f900,0xfd04da2330c917ee,0x13ea34cdde27f900,0xfd04da2330c917ee,
-0xd2eba39a48713900,0xa198d0e93b024a73,0xd2eba39a48713900,0xa198d0e93b024a73,
-0xd3a284f526577100,0xb0c1e79645341263,0xd3a284f526577100,0xb0c1e79645341263,
-0x891e05921b8c9700,0x83140f9811869d0a,0x891e05921b8c9700,0x83140f9811869d0a,
-0x1fa33c809f23bc00,0xb30f902c338f10ac,0x1fa33c809f23bc00,0xb30f902c338f10ac,
-0x2542cbac89ee6700,0x166ef88adca4324,0x2542cbac89ee6700,0x166ef88adca4324,
-0x15342b0a1f3e2100,0x86a7b8998cadb293,0x15342b0a1f3e2100,0x86a7b8998cadb293,
-0x32d05bb98b69e200,0xfc1e957745a72cce,0x32d05bb98b69e200,0xfc1e957745a72cce,
-0xed3ffc2ec311d200,0x2bf93ae805d714c6,0xed3ffc2ec311d200,0x2bf93ae805d714c6,
-0x5b3f64643f5b00,0xf2a9cd9696cda9f2,0x5b3f64643f5b00,0xf2a9cd9696cda9f2,
-0xb18885bc0d343900,0x774e437acbf2ffc6,0xb18885bc0d343900,0x774e437acbf2ffc6,
-0x7a1f41245e3b6500,0x9affa1c4bedb85e0,0x7a1f41245e3b6500,0x9affa1c4bedb85e0,
-0x11aa0db6a71cbb00,0x2893348f9e258239,0x11aa0db6a71cbb00,0x2893348f9e258239,
-0x2defad6f4280c200,0xc90b498ba66426e4,0x2defad6f4280c200,0xc90b498ba66426e4,
-0x5e51fdf2aca30f00,0x6768c4cb959a3639,0x5e51fdf2aca30f00,0x6768c4cb959a3639,
-0xded84b4d93950600,0x2721b2b46a6cfff9,0xded84b4d93950600,0x2721b2b46a6cfff9,
-0xad54c33a976ef900,0x1ce5728b26df48b1,0xad54c33a976ef900,0x1ce5728b26df48b1,
-0xb6f1d99e286f4700,0x82c5edaa1c5b7334,0xb6f1d99e286f4700,0x82c5edaa1c5b7334,
-0x3681cb7c4afdb700,0x3285cf784ef9b304,0x3681cb7c4afdb700,0x3285cf784ef9b304,
-0x9f3e51f06fcea100,0xa1006fce51f09f3e,0x9f3e51f06fcea100,0xa1006fce51f09f3e,
-0x9288a2b82a301a00,0x415b716bf9e3c9d3,0x9288a2b82a301a00,0x415b716bf9e3c9d3,
-0x7b072458235f7c00,0x770b28542f53700c,0x7b072458235f7c00,0x770b28542f53700c,
-0xd7da6e63b4b90d00,0x808d3934e3ee5a57,0xd7da6e63b4b90d00,0x808d3934e3ee5a57,
-0x2b9b40f0db6bb00,0xb40f02b9bb000db6,0x2b9b40f0db6bb00,0xb40f02b9bb000db6,
-0x32264b5f6d791400,0x1d09647042563b2f,0x32264b5f6d791400,0x1d09647042563b2f,
-0x8803cb4bc348800,0x2ba31f979f17ab23,0x8803cb4bc348800,0x2ba31f979f17ab23,
-0x58ea49fba311b200,0xa91bb80a52e043f1,0x58ea49fba311b200,0xa91bb80a52e043f1,
-0xb0698c55e53cd900,0x3fe603da6ab3568f,0xb0698c55e53cd900,0x3fe603da6ab3568f,
-0x2178376e4f165900,0xe7bef1a889d09fc6,0x2178376e4f165900,0xe7bef1a889d09fc6,
-0xb141a959e818f000,0xb848a050e111f909,0xb141a959e818f000,0xb848a050e111f909,
-0x5d951cd48941c800,0xd81099510cc44d85,0x5d951cd48941c800,0xd81099510cc44d85,
-0xa21d7dc260dfbf00,0x69d6b609ab1474cb,0xa21d7dc260dfbf00,0x69d6b609ab1474cb,
-0x23ba3ea7841d9900,0xac35b1280b92168f,0x23ba3ea7841d9900,0xac35b1280b92168f,
-0x56e9912e78c7bf00,0xeb1c976209fe758,0x56e9912e78c7bf00,0xeb1c976209fe758,
-0xc60ce228ee24ca00,0xe329c70dcb01ef25,0xc60ce228ee24ca00,0xe329c70dcb01ef25,
-0xef8a2d48a7c26500,0x97f25530dfba1d78,0xef8a2d48a7c26500,0x97f25530dfba1d78,
-0x46ab18f5b35eed00,0xa64bf81553be0de0,0x46ab18f5b35eed00,0xa64bf81553be0de0,
-0xe67f54cd2bb29900,0x930a21b85ec7ec75,0xe67f54cd2bb29900,0x930a21b85ec7ec75,
-0xf01cde32c22eec00,0x40ac6e82729e5cb0,0xf01cde32c22eec00,0x40ac6e82729e5cb0,
-0xd612cb0fd91dc400,0xdb1fc602d410c90d,0xd612cb0fd91dc400,0xdb1fc602d410c90d,
-0x885f69be36e1d700,0xaf784e9911c6f027,0x885f69be36e1d700,0xaf784e9911c6f027,
-0xa1b05544e5f41100,0x6b7a9f8e2f3edbca,0xa1b05544e5f41100,0x6b7a9f8e2f3edbca,
-0x3e126448765a2c00,0x8ba7d1fdc3ef99b5,0x3e126448765a2c00,0x8ba7d1fdc3ef99b5,
-0x4ebb1beea055f500,0xc03595602edb7b8e,0x4ebb1beea055f500,0xc03595602edb7b8e,
-0xcbfbaa9a51613000,0xae9ecfff34045565,0xcbfbaa9a51613000,0xae9ecfff34045565,
-0x6e970ff69861f900,0xe41d857c12eb738a,0x6e970ff69861f900,0xe41d857c12eb738a,
-0x94dbaae5713e4f00,0x216e1f50c48bfab5,0x94dbaae5713e4f00,0x216e1f50c48bfab5,
-0x2ad4be406a94fe00,0xbb452fd1fb056f91,0x2ad4be406a94fe00,0xbb452fd1fb056f91,
-0x84c7783bbffc4300,0x4003bcff7b3887c4,0x84c7783bbffc4300,0x4003bcff7b3887c4,
-0x508969b9e930d00,0x505dc3cecbc65855,0x508969b9e930d00,0x505dc3cecbc65855,
-0xe85a4ffd15a7b200,0xbf0d18aa42f0e557,0xe85a4ffd15a7b200,0xbf0d18aa42f0e557,
-0x16739df8ee8b6500,0xa8cd23465035dbbe,0x16739df8ee8b6500,0xa8cd23465035dbbe,
-0x175594d6c1834200,0x6f2decaeb9fb3a78,0x175594d6c1834200,0x6f2decaeb9fb3a78,
-0xee901f618ff17e00,0x5b25aad43a44cbb5,0xee901f618ff17e00,0x5b25aad43a44cbb5,
-0x98a65c62fac43e00,0x221ce6d8407e84ba,0x98a65c62fac43e00,0x221ce6d8407e84ba,
-0x10f32ac9d93ae300,0x4e73eddcd2ef714,0x10f32ac9d93ae300,0x4e73eddcd2ef714,
-0xd31123e132f0c200,0x69ab995b884a78ba,0xd31123e132f0c200,0x69ab995b884a78ba,
-0x695daa9ef7c33400,0xb28671452c18efdb,0x695daa9ef7c33400,0xb28671452c18efdb,
-0xffb5cf857a304a00,0xeea4de946b215b11,0xffb5cf857a304a00,0xeea4de946b215b11,
-0xfd08aa5fa257f500,0x9065c732cf3a986d,0xfd08aa5fa257f500,0x9065c732cf3a986d,
-0xce604be52b85ae00,0xd17f54fa349ab11f,0xce604be52b85ae00,0xd17f54fa349ab11f,
-0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf,0xd7ac6a11c6bd7b00,0x6813d5ae7902c4bf,
-0x9b4a66b72cfdd100,0x3cedc1108b5a76a7,0x9b4a66b72cfdd100,0x3cedc1108b5a76a7,
-0x98ab5261f9ca3300,0xdfec1526be8d7447,0x98ab5261f9ca3300,0xdfec1526be8d7447,
-0x2ce1bf725e93cd00,0xd71a4489a56836fb,0x2ce1bf725e93cd00,0xd71a4489a56836fb,
-0xb6adb4af19021b00,0xc5dec7dc6a716873,0xb6adb4af19021b00,0xc5dec7dc6a716873,
-0xa960935af33ac900,0x6ea7549d34fd0ec7,0xa960935af33ac900,0x6ea7549d34fd0ec7,
-0xe2a57e39db9c4700,0x8ccb1057b5f2296e,0xe2a57e39db9c4700,0x8ccb1057b5f2296e,
-0x357a9ad5e0af4f00,0x1956b6f9cc83632c,0x357a9ad5e0af4f00,0x1956b6f9cc83632c,
-0x2583832500a6a600,0xd37575d3f65050f6,0x2583832500a6a600,0xd37575d3f65050f6,
-0x6d646f660b020900,0xa6afa4adc0c9c2cb,0x6d646f660b020900,0xa6afa4adc0c9c2cb,
-0x8135c672f347b400,0xb105f642c3778430,0x8135c672f347b400,0xb105f642c3778430,
-0x4916c29dd48b5f00,0x5a05d18ec7984c13,0x4916c29dd48b5f00,0x5a05d18ec7984c13,
-0xa45cfb03a75ff800,0x52aa0df551a90ef6,0xa45cfb03a75ff800,0x52aa0df551a90ef6,
-0xcfefdafa35152000,0x14340121eecefbdb,0xcfefdafa35152000,0x14340121eecefbdb,
-0xce7c2a9856e4b200,0x7bc99f2de35107b5,0xce7c2a9856e4b200,0x7bc99f2de35107b5,
-0xf006e711e117f600,0x996f8e78887e9f69,0xf006e711e117f600,0x996f8e78887e9f69,
-0x520b94cd9fc65900,0xcd940b520059c69f,0x520b94cd9fc65900,0xcd940b520059c69f,
-0x534ca7b8ebf41f00,0x78678c93c0df342b,0x534ca7b8ebf41f00,0x78678c93c0df342b,
-0x7d668b90edf61b00,0x776c819ae7fc110a,0x7d668b90edf61b00,0x776c819ae7fc110a,
-0xf2dfcde0123f2d00,0x210c1e33c1ecfed3,0xf2dfcde0123f2d00,0x210c1e33c1ecfed3,
-0xfe0a5fab55a1f400,0x6c98cd39c7336692,0xfe0a5fab55a1f400,0x6c98cd39c7336692,
-0xb8b26c66ded40a00,0x707aa4ae161cc2c8,0xb8b26c66ded40a00,0x707aa4ae161cc2c8,
-0xcfde0e1fd0c11100,0xe5f42435faeb3b2a,0xcfde0e1fd0c11100,0xe5f42435faeb3b2a,
-0xa9947b46efd23d00,0x211cf3ce675ab588,0xa9947b46efd23d00,0x211cf3ce675ab588,
-0xd96be95b8230b200,0xb80a883ae351d361,0xd96be95b8230b200,0xb80a883ae351d361,
-0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce,0x707bdbd0a0ab0b00,0xbeb5151e6e65c5ce,
-0x9cef790a96e57300,0xd4a73142dead3b48,0x9cef790a96e57300,0xd4a73142dead3b48,
-0x9f065ec758c19900,0xd24b138a158cd44d,0x9f065ec758c19900,0xd24b138a158cd44d,
-0xfe8d2457a9da7300,0xe291384bb5c66f1c,0xfe8d2457a9da7300,0xe291384bb5c66f1c,
-0xd5ef0e34e1db3a00,0x251ffec4112bcaf0,0xd5ef0e34e1db3a00,0x251ffec4112bcaf0,
-0x97f61879ee8f6100,0x7e1ff190076688e9,0x97f61879ee8f6100,0x7e1ff190076688e9,
-0x4040040444440000,0xf3f3b7b7f7f7b3b3,0x4040040444440000,0xf3f3b7b7f7f7b3b3,
-0xa8a7333c949b0f00,0x1817838c242bbfb0,0xa8a7333c949b0f00,0x1817838c242bbfb0,
-0x50a34dbeee1df300,0x2cdf31c292618f7c,0x50a34dbeee1df300,0x2cdf31c292618f7c,
-0xaebb2c3997821500,0x4055c2d7796cfbee,0xaebb2c3997821500,0x4055c2d7796cfbee,
-0x1743d48493c7500,0x97e2abdedfaae396,0x1743d48493c7500,0x97e2abdedfaae396,
-0x9b983033a8ab0300,0x8a892122b9ba1211,0x9b983033a8ab0300,0x8a892122b9ba1211,
-0x442b026d29466f00,0x4629006f2b446d02,0x442b026d29466f00,0x4629006f2b446d02,
-0x2d96d06b46fdbb00,0x8c3771cae75c1aa1,0x2d96d06b46fdbb00,0x8c3771cae75c1aa1,
-0x765d466d1b302b00,0x84afb49fe9c2d9f2,0x765d466d1b302b00,0x84afb49fe9c2d9f2,
-0xecf94555b9ac100,0x80411adbd5144f8e,0xecf94555b9ac100,0x80411adbd5144f8e,
-0xbb354ece75fb800,0x348c6bd3d860873f,0xbb354ece75fb800,0x348c6bd3d860873f,
-0xec67840fe3688b00,0xf972911af67d9e15,0xec67840fe3688b00,0xf972911af67d9e15,
-0x611f522c4d337e00,0x84fab7c9a8d69be5,0x611f522c4d337e00,0x84fab7c9a8d69be5,
-0xf55079dc298ca500,0x49ecc560953019bc,0xf55079dc298ca500,0x49ecc560953019bc,
-0xe35845fe1da6bb00,0x10abb60dee5548f3,0xe35845fe1da6bb00,0x10abb60dee5548f3,
-0x11a408bdac19b500,0x6bde72c7d663cf7a,0x11a408bdac19b500,0x6bde72c7d663cf7a,
-0x3b612f754e145a00,0x9fc58bd1eab0fea4,0x3b612f754e145a00,0x9fc58bd1eab0fea4,
-0xf6ff8d84727b0900,0x373e4c45b3bac8c1,0xf6ff8d84727b0900,0x373e4c45b3bac8c1,
-0xa7339307a0349400,0x31a5059136a20296,0xa7339307a0349400,0x31a5059136a20296,
-0x601d7d00601d7d00,0x4f32522f4f32522f,0x601d7d00601d7d00,0x4f32522f4f32522f,
-0xb9d1593188e06800,0x5830b8d0690189e1,0xb9d1593188e06800,0x5830b8d0690189e1,
-0x9c7319f66a85ef00,0x937c16f9658ae00f,0x9c7319f66a85ef00,0x937c16f9658ae00f,
-0xb769ca14a37dde00,0x27f95a8433ed4e90,0xb769ca14a37dde00,0x27f95a8433ed4e90,
-0xc32134d615f7e200,0x9674618340a2b755,0xc32134d615f7e200,0x9674618340a2b755,
-0x4e6c6a4806242200,0x391b1d3f71535577,0x4e6c6a4806242200,0x391b1d3f71535577,
-0x68312f761e475900,0xb9e0fea7cf9688d1,0x68312f761e475900,0xb9e0fea7cf9688d1,
-0xd30571a774a2d600,0x9c4a3ee83bed994f,0xd30571a774a2d600,0x9c4a3ee83bed994f,
-0x8990dfc64f561900,0x7e672831b8a1eef7,0x8990dfc64f561900,0x7e672831b8a1eef7,
-0x2023a2a181820300,0xbfbc3d3e1e1d9c9f,0x2023a2a181820300,0xbfbc3d3e1e1d9c9f,
-0xe26956dd3fb48b00,0xac27189371fac54e,0xe26956dd3fb48b00,0xac27189371fac54e,
-0xd95f2ea871f78600,0x66e09117ce4839bf,0xd95f2ea871f78600,0x66e09117ce4839bf,
-0x159d76feeb638800,0x1d957ef6e36b8008,0x159d76feeb638800,0x1d957ef6e36b8008,
-0xebebc3c328280000,0x24240c0ce7e7cfcf,0xebebc3c328280000,0x24240c0ce7e7cfcf,
-0x95ba022db8972f00,0x3f10a887123d85aa,0x95ba022db8972f00,0x3f10a887123d85aa,
-0x4a53554c061f1900,0xd3caccd59f868099,0x4a53554c061f1900,0xd3caccd59f868099,
-0xebd3f6ce251d3800,0xb189ac947f47625a,0xebd3f6ce251d3800,0xb189ac947f47625a,
-0x7db9e92d5094c400,0xc1055591ec2878bc,0x7db9e92d5094c400,0xc1055591ec2878bc,
-0x6ac00aaac06aa00,0x4de74be1e74de14b,0x6ac00aaac06aa00,0x4de74be1e74de14b,
-0x37669fcef9a85100,0xd4857c2d1a4bb2e3,0x37669fcef9a85100,0xd4857c2d1a4bb2e3,
-0xd618c00ed816ce00,0x3af42ce234fa22ec,0xd618c00ed816ce00,0x3af42ce234fa22ec,
-0x22cd739cbe51ef00,0x9a75cb2406e957b8,0x22cd739cbe51ef00,0x9a75cb2406e957b8,
-0xa2b64652f0e41400,0x617585913327d7c3,0xa2b64652f0e41400,0x617585913327d7c3,
-0x3c0de1d1eddc300,0xb47769aaa96a74b7,0x3c0de1d1eddc300,0xb47769aaa96a74b7,
-0xaa771dcd67bad00,0x2c8157faf05d8b26,0xaa771dcd67bad00,0x2c8157faf05d8b26,
-0x870aa429ae238d00,0x61ec42cf48c56be6,0x870aa429ae238d00,0x61ec42cf48c56be6,
-0x5ae3b90953eab00,0xca61f45f5af164cf,0x5ae3b90953eab00,0xca61f45f5af164cf,
-0xbc215bc67ae79d00,0xf16c168b37aad04d,0xbc215bc67ae79d00,0xf16c168b37aad04d,
-0x4cd01b87cb579c00,0xc458930f43df1488,0x4cd01b87cb579c00,0xc458930f43df1488,
-0x7405651460117100,0xfd8cec9de998f889,0x7405651460117100,0xfd8cec9de998f889,
-0xf812d832ca20ea00,0x816ba14bb3599379,0xf812d832ca20ea00,0x816ba14bb3599379,
-0xdf7c53f02f8ca300,0xf55679da05a6892a,0xdf7c53f02f8ca300,0xf55679da05a6892a,
-0x16685e2036487e00,0x57b4d33255b6d13,0x16685e2036487e00,0x57b4d33255b6d13,
-0x4d24e78ec3aa6900,0x69aac38ee7244d,0x4d24e78ec3aa6900,0x69aac38ee7244d,
-0xf4853c4db9c87100,0x413089f80c7dc4b5,0xf4853c4db9c87100,0x413089f80c7dc4b5,
-0x237a451c3f665900,0xecb58ad3f0a996cf,0x237a451c3f665900,0xecb58ad3f0a996cf,
-0x5206b4e4b6e2500,0x83a6edc8cde8a386,0x5206b4e4b6e2500,0x83a6edc8cde8a386,
-0x434358581b1b0000,0xacacb7b7f4f4efef,0x434358581b1b0000,0xacacb7b7f4f4efef,
-0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc,0x2ccc9a7a56b6e000,0x907026c6ea0a5cbc,
-0x5825a7da82ff7d00,0x88f5770a522fadd0,0x5825a7da82ff7d00,0x88f5770a522fadd0,
-0x26fb7da0865bdd00,0x7ea325f8de038558,0x26fb7da0865bdd00,0x7ea325f8de038558,
-0x133c002f3c132f00,0xecc3ffd0c3ecd0ff,0x133c002f3c132f00,0xecc3ffd0c3ecd0ff,
-0x8aa97556dcff2300,0xb695496ae0c31f3c,0x8aa97556dcff2300,0xb695496ae0c31f3c,
-0x7d067b0b760d700,0x7aad1acdca1daa7d,0x7d067b0b760d700,0x7aad1acdca1daa7d,
-0xb0c3e49727547300,0xc5b691e252210675,0xb0c3e49727547300,0xc5b691e252210675,
-0x420cc789cb854e00,0x622ce7a9eba56e20,0x420cc789cb854e00,0x622ce7a9eba56e20,
-0x4d3abbcc81f67700,0x5225a4d39ee9681f,0x4d3abbcc81f67700,0x5225a4d39ee9681f,
-0x5192e32071b2c300,0xbe7d0ccf9e5d2cef,0x5192e32071b2c300,0xbe7d0ccf9e5d2cef,
-0x3b7482cdf6b94f00,0xca85733c0748bef1,0x3b7482cdf6b94f00,0xca85733c0748bef1,
-0xfb451ca259e7be00,0xb00e57e912acf54b,0xfb451ca259e7be00,0xb00e57e912acf54b,
-0x8f1ee372fd6c9100,0x9809f465ea7b8617,0x8f1ee372fd6c9100,0x9809f465ea7b8617,
-0x7784956611e2f300,0xa85b4ab9ce3d2cdf,0x7784956611e2f300,0xa85b4ab9ce3d2cdf,
-0xc0de5e4e8e90100,0xa0be3e2eeef0706,0xc0de5e4e8e90100,0xa0be3e2eeef0706,
-0xe92b8644ad6fc200,0x5a9835f71edc71b3,0xe92b8644ad6fc200,0x5a9835f71edc71b3,
-0x67256b294e0c4200,0xda98d694f3b1ffbd,0x67256b294e0c4200,0xda98d694f3b1ffbd,
-0xc7dd4a5a9d87100,0xd3a20b7a7607aedf,0xc7dd4a5a9d87100,0xd3a20b7a7607aedf,
-0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620,0x90e68bfd6d1b7600,0xb0c6abdd4d3b5620,
-0x2b73fba388d05800,0xc79f174f643cb4ec,0x2b73fba388d05800,0xc79f174f643cb4ec,
-0xbe91022d93bc2f00,0xa38c1f308ea1321d,0xbe91022d93bc2f00,0xa38c1f308ea1321d,
-0x79e622bdc45b9f00,0xb926e27d049b5fc0,0x79e622bdc45b9f00,0xb926e27d049b5fc0,
-};
diff --git a/trunc_btfy_tab.h b/trunc_btfy_tab.h
deleted file mode 100644
index ca44895..0000000
--- a/trunc_btfy_tab.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#ifndef _TRUNC_BTFY_TAB_H_
-#define _TRUNC_BTFY_TAB_H_
-
-#include "stdint.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-extern uint64_t beta_mul_64 [];
-
-extern uint64_t i_beta_mul_64 [];
-
-
-
-extern uint64_t beta_mul_64_bm4r [];
-
-extern uint64_t i_beta_mul_64_bm4r [];
-
-extern uint64_t beta_mul_64_bm4r_ext_8 [];
-
-extern uint64_t i_beta_mul_64_bm4r_ext_8 [];
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
diff --git a/trunc_btfy_tab_64.c b/trunc_btfy_tab_64.c
deleted file mode 100644
index 847893c..0000000
--- a/trunc_btfy_tab_64.c
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#include "stdint.h"
-
-
-
-uint64_t beta_mul_32 [64] __attribute__((aligned(32))) = {
-0x1,
-0xed57ce778f0d6244,
-0xb66864e6ec14b4d2,
-0x9cedebc39773a213,
-0x54e5bf3774b3f850,
-0xaa41ec72aca4d601,
-0x4943d209fdc449b8,
-0x6e9a7c0e6d89dc84,
-0xeb42e79f91f49f8c,
-0x5dc314ada2848ba2,
-0x503cdedab981d32c,
-0x21d93ab94919cfd3,
-0x4553b41bda2fbec8,
-0xcb47a62d21df0b4d,
-0x4639691aa527dbba,
-0xe032e7a43c3d150f,
-0xb0f502e4cd60039a,
-0xf8287767660ad2b4,
-0x1dbf8d7727fc654e,
-0x19b12a51dacba79e,
-0xe691d7c0794c614d,
-0x28cf418faf97a29f,
-0xfc5c2bca45c931c,
-0x4cb433e14292028e,
-0x189b29840c130e7f,
-0x315f35290c617710,
-0x1f4a9de7438026b,
-0x6aea5df783dd08ef,
-0xb36ae8e530273635,
-0x837b54ac6006165d,
-0x49216693bb420e26,
-0xfd50e246ba0fe1a8,
-0x57a3104fcd0e5f34,
-0xbfbbcc4e6e818ce9,
-0x4ff85cdbb8b5a385,
-0xe5836ac7d88636ff,
-0xacaee33d357e7115,
-0xd5591c1e1fcd94ac,
-0x5a80ddb4eb880892,
-0x557feec300cdaab7,
-0x5a3fd6353ee07e37,
-0x5c467f7d2caf0e9f,
-0xeaac97005f61500b,
-0x9554e988c2331d19,
-0x46fc62831b042eeb,
-0xe89bd07ebe5cbadc,
-0xe442a47d4ab744e,
-0x492fcd9722316b93,
-0xb86431a85814f803,
-0xa3c96aff342c82b8,
-0x4716ccf6cbc75a1a,
-0x5b71bea40e882374,
-0x54ac9ee9b21ebe6e,
-0x1aac7f922b29c823,
-0x49a5f74a2ecb3e44,
-0x4a5a968cc3b566d1,
-0x641ddcf92a60aa5,
-0xee004d8f989dba16,
-0x1c2242e610c9cd6a,
-0x59f1654505010e32,
-0xd8df39e76c0e7b7,
-0x8cf8e69eb14ecfb4,
-0xcb8c5396572fc44,
-0x3b278b84a916e44c,
-};
-
-
-uint64_t i_beta_mul_32 [64] __attribute__((aligned(32))) = {
-0x1,
-0x8961b8a7841bfc6,
-0xfd56dc6306e45ec6,
-0x77332469d0404105,
-0xd110eb4a970feaf5,
-0x9c94931de38226fe,
-0x52bf8c5ba0978896,
-0xbce2b823bebf0166,
-0x7af3356b5d818e41,
-0x1e7b94c935b698d0,
-0xbcb73d9aabdd6ddf,
-0x5f75970481f366a8,
-0xb33f7074d9b6e3fe,
-0x2adb64d29a93ef96,
-0x59dab92a69394e60,
-0x3c8004790328459c,
-0xadcb0001cdaa3d05,
-0x9bb38fd76d5e0c0b,
-0xabcadd426cb54b4d,
-0xf042a8f93e8a48b9,
-0x47b25aab146986f6,
-0xe750955be42931a1,
-0x9bf1d4a1535a0d17,
-0x91564f9a406d933c,
-0xded3254b42d33aaa,
-0xbd1f32c59e84e45d,
-0xfa018660e3165396,
-0xa2f911a00f5baa7b,
-0xe958695bc8926acd,
-0xc8c10606a8ec8d6b,
-0x8e6cfef54b2e9ac6,
-0x88007d210e507cf4,
-0x17a89b9796a48397,
-0x1bdd636a99f218be,
-0x7cb821d83481a449,
-0xff39584957728d46,
-0x9cd7c0f7b4d02de7,
-0x779fca946b676edb,
-0x5235a7728b715838,
-0x70ef0482c08984a5,
-0xbb1c3dbfe2b5150b,
-0xee767356051fe0e1,
-0x1b5c98d75cc93fe8,
-0x4c25ee1fb1c8ceb6,
-0xb7310079067f9e51,
-0x4be2a5ae359e2594,
-0xfe86864026631c3,
-0x5b4cd59958434683,
-0xe550b2539a848707,
-0x6e50d13b6a7a5997,
-0x7fd8fb00a5aef99a,
-0xcdbd262ac16e806b,
-0xc021427b4f7646e0,
-0xd7f262605a9bcdd0,
-0xb046630a7efeddc,
-0xa869f3dfcbe24fab,
-0xa00150323be9b1de,
-0x1294d8724ae3d0d,
-0x4ab517f07f03a4b1,
-0xfdc5af3bb370e266,
-0x2aff63efa8285238,
-0xfba0ace42227357a,
-0xc208107e1c3e5ac1,
-0xb2dbb5cb68d0dc74,
-};
-
-
-
-uint64_t beta_mul_32_m4r [(64/4)*16] __attribute__((aligned(32))) = {
-0x0,
-0x1,
-0xed57ce778f0d6244,
-0xed57ce778f0d6245,
-0xb66864e6ec14b4d2,
-0xb66864e6ec14b4d3,
-0x5b3faa916319d696,
-0x5b3faa916319d697,
-0x9cedebc39773a213,
-0x9cedebc39773a212,
-0x71ba25b4187ec057,
-0x71ba25b4187ec056,
-0x2a858f257b6716c1,
-0x2a858f257b6716c0,
-0xc7d24152f46a7485,
-0xc7d24152f46a7484,
-0x0,
-0x54e5bf3774b3f850,
-0xaa41ec72aca4d601,
-0xfea45345d8172e51,
-0x4943d209fdc449b8,
-0x1da66d3e8977b1e8,
-0xe3023e7b51609fb9,
-0xb7e7814c25d367e9,
-0x6e9a7c0e6d89dc84,
-0x3a7fc339193a24d4,
-0xc4db907cc12d0a85,
-0x903e2f4bb59ef2d5,
-0x27d9ae07904d953c,
-0x733c1130e4fe6d6c,
-0x8d9842753ce9433d,
-0xd97dfd42485abb6d,
-0x0,
-0xeb42e79f91f49f8c,
-0x5dc314ada2848ba2,
-0xb681f3323370142e,
-0x503cdedab981d32c,
-0xbb7e394528754ca0,
-0xdffca771b05588e,
-0xe6bd2de88af1c702,
-0x21d93ab94919cfd3,
-0xca9bdd26d8ed505f,
-0x7c1a2e14eb9d4471,
-0x9758c98b7a69dbfd,
-0x71e5e463f0981cff,
-0x9aa703fc616c8373,
-0x2c26f0ce521c975d,
-0xc7641751c3e808d1,
-0x0,
-0x4553b41bda2fbec8,
-0xcb47a62d21df0b4d,
-0x8e141236fbf0b585,
-0x4639691aa527dbba,
-0x36add017f086572,
-0x8d7ecf3784f8d0f7,
-0xc82d7b2c5ed76e3f,
-0xe032e7a43c3d150f,
-0xa56153bfe612abc7,
-0x2b7541891de21e42,
-0x6e26f592c7cda08a,
-0xa60b8ebe991aceb5,
-0xe3583aa54335707d,
-0x6d4c2893b8c5c5f8,
-0x281f9c8862ea7b30,
-0x0,
-0xb0f502e4cd60039a,
-0xf8287767660ad2b4,
-0x48dd7583ab6ad12e,
-0x1dbf8d7727fc654e,
-0xad4a8f93ea9c66d4,
-0xe597fa1041f6b7fa,
-0x5562f8f48c96b460,
-0x19b12a51dacba79e,
-0xa94428b517aba404,
-0xe1995d36bcc1752a,
-0x516c5fd271a176b0,
-0x40ea726fd37c2d0,
-0xb4fba5c23057c14a,
-0xfc26d0419b3d1064,
-0x4cd3d2a5565d13fe,
-0x0,
-0xe691d7c0794c614d,
-0x28cf418faf97a29f,
-0xce5e964fd6dbc3d2,
-0xfc5c2bca45c931c,
-0xe954157cdd10f251,
-0x270a83330bcb3183,
-0xc19b54f3728750ce,
-0x4cb433e14292028e,
-0xaa25e4213bde63c3,
-0x647b726eed05a011,
-0x82eaa5ae9449c15c,
-0x4371f15de6ce9192,
-0xa5e0269d9f82f0df,
-0x6bbeb0d24959330d,
-0x8d2f671230155240,
-0x0,
-0x189b29840c130e7f,
-0x315f35290c617710,
-0x29c41cad0072796f,
-0x1f4a9de7438026b,
-0x196f805a782b0c14,
-0x30ab9cf77859757b,
-0x2830b573744a7b04,
-0x6aea5df783dd08ef,
-0x727174738fce0690,
-0x5bb568de8fbc7fff,
-0x432e415a83af7180,
-0x6b1ef429f7e50a84,
-0x7385ddadfbf604fb,
-0x5a41c100fb847d94,
-0x42dae884f79773eb,
-0x0,
-0xb36ae8e530273635,
-0x837b54ac6006165d,
-0x3011bc4950212068,
-0x49216693bb420e26,
-0xfa4b8e768b653813,
-0xca5a323fdb44187b,
-0x7930dadaeb632e4e,
-0xfd50e246ba0fe1a8,
-0x4e3a0aa38a28d79d,
-0x7e2bb6eada09f7f5,
-0xcd415e0fea2ec1c0,
-0xb47184d5014def8e,
-0x71b6c30316ad9bb,
-0x370ad079614bf9d3,
-0x8460389c516ccfe6,
-0x0,
-0x57a3104fcd0e5f34,
-0xbfbbcc4e6e818ce9,
-0xe818dc01a38fd3dd,
-0x4ff85cdbb8b5a385,
-0x185b4c9475bbfcb1,
-0xf0439095d6342f6c,
-0xa7e080da1b3a7058,
-0xe5836ac7d88636ff,
-0xb2207a88158869cb,
-0x5a38a689b607ba16,
-0xd9bb6c67b09e522,
-0xaa7b361c6033957a,
-0xfdd82653ad3dca4e,
-0x15c0fa520eb21993,
-0x4263ea1dc3bc46a7,
-0x0,
-0xacaee33d357e7115,
-0xd5591c1e1fcd94ac,
-0x79f7ff232ab3e5b9,
-0x5a80ddb4eb880892,
-0xf62e3e89def67987,
-0x8fd9c1aaf4459c3e,
-0x23772297c13bed2b,
-0x557feec300cdaab7,
-0xf9d10dfe35b3dba2,
-0x8026f2dd1f003e1b,
-0x2c8811e02a7e4f0e,
-0xfff3377eb45a225,
-0xa351d04ade3bd330,
-0xdaa62f69f4883689,
-0x7608cc54c1f6479c,
-0x0,
-0x5a3fd6353ee07e37,
-0x5c467f7d2caf0e9f,
-0x679a948124f70a8,
-0xeaac97005f61500b,
-0xb093413561812e3c,
-0xb6eae87d73ce5e94,
-0xecd53e484d2e20a3,
-0x9554e988c2331d19,
-0xcf6b3fbdfcd3632e,
-0xc91296f5ee9c1386,
-0x932d40c0d07c6db1,
-0x7ff87e889d524d12,
-0x25c7a8bda3b23325,
-0x23be01f5b1fd438d,
-0x7981d7c08f1d3dba,
-0x0,
-0x46fc62831b042eeb,
-0xe89bd07ebe5cbadc,
-0xae67b2fda5589437,
-0xe442a47d4ab744e,
-0x48b848c4cfaf5aa5,
-0xe6dffa396af7ce92,
-0xa02398ba71f3e079,
-0x492fcd9722316b93,
-0xfd3af1439354578,
-0xa1b41de99c6dd14f,
-0xe7487f6a8769ffa4,
-0x476be7d0f69a1fdd,
-0x1978553ed9e3136,
-0xaff037ae48c6a501,
-0xe90c552d53c28bea,
-0x0,
-0xb86431a85814f803,
-0xa3c96aff342c82b8,
-0x1bad5b576c387abb,
-0x4716ccf6cbc75a1a,
-0xff72fd5e93d3a219,
-0xe4dfa609ffebd8a2,
-0x5cbb97a1a7ff20a1,
-0x5b71bea40e882374,
-0xe3158f0c569cdb77,
-0xf8b8d45b3aa4a1cc,
-0x40dce5f362b059cf,
-0x1c677252c54f796e,
-0xa40343fa9d5b816d,
-0xbfae18adf163fbd6,
-0x7ca2905a97703d5,
-0x0,
-0x54ac9ee9b21ebe6e,
-0x1aac7f922b29c823,
-0x4e00e17b9937764d,
-0x49a5f74a2ecb3e44,
-0x1d0969a39cd5802a,
-0x530988d805e2f667,
-0x7a51631b7fc4809,
-0x4a5a968cc3b566d1,
-0x1ef6086571abd8bf,
-0x50f6e91ee89caef2,
-0x45a77f75a82109c,
-0x3ff61c6ed7e5895,
-0x5753ff2f5f60e6fb,
-0x19531e54c65790b6,
-0x4dff80bd74492ed8,
-0x0,
-0x641ddcf92a60aa5,
-0xee004d8f989dba16,
-0xe84190400a3bb0b3,
-0x1c2242e610c9cd6a,
-0x1a639f29826fc7cf,
-0xf2220f698854777c,
-0xf463d2a61af27dd9,
-0x59f1654505010e32,
-0x5fb0b88a97a70497,
-0xb7f128ca9d9cb424,
-0xb1b0f5050f3abe81,
-0x45d327a315c8c358,
-0x4392fa6c876ec9fd,
-0xabd36a2c8d55794e,
-0xad92b7e31ff373eb,
-0x0,
-0xd8df39e76c0e7b7,
-0x8cf8e69eb14ecfb4,
-0x81751500c78e2803,
-0xcb8c5396572fc44,
-0x13536a713b21bf3,
-0x804023a7d43c33f0,
-0x8dcdd039a2fcd447,
-0x3b278b84a916e44c,
-0x36aa781adfd603fb,
-0xb7df6d1a18582bf8,
-0xba529e846e98cc4f,
-0x379f4ebdcc641808,
-0x3a12bd23baa4ffbf,
-0xbb67a8237d2ad7bc,
-0xb6ea5bbd0bea300b,
-};
-
-
-uint64_t i_beta_mul_32_m4r [(64/4)*16] __attribute__((aligned(32))) = {
-0x0,
-0x1,
-0x8961b8a7841bfc6,
-0x8961b8a7841bfc7,
-0xfd56dc6306e45ec6,
-0xfd56dc6306e45ec7,
-0xf5c0c7e97ea5e100,
-0xf5c0c7e97ea5e101,
-0x77332469d0404105,
-0x77332469d0404104,
-0x7fa53fe3a801fec3,
-0x7fa53fe3a801fec2,
-0x8a65f80ad6a41fc3,
-0x8a65f80ad6a41fc2,
-0x82f3e380aee5a005,
-0x82f3e380aee5a004,
-0x0,
-0xd110eb4a970feaf5,
-0x9c94931de38226fe,
-0x4d847857748dcc0b,
-0x52bf8c5ba0978896,
-0x83af671137986263,
-0xce2b1f464315ae68,
-0x1f3bf40cd41a449d,
-0xbce2b823bebf0166,
-0x6df2536929b0eb93,
-0x20762b3e5d3d2798,
-0xf166c074ca32cd6d,
-0xee5d34781e2889f0,
-0x3f4ddf3289276305,
-0x72c9a765fdaaaf0e,
-0xa3d94c2f6aa545fb,
-0x0,
-0x7af3356b5d818e41,
-0x1e7b94c935b698d0,
-0x6488a1a268371691,
-0xbcb73d9aabdd6ddf,
-0xc64408f1f65ce39e,
-0xa2cca9539e6bf50f,
-0xd83f9c38c3ea7b4e,
-0x5f75970481f366a8,
-0x2586a26fdc72e8e9,
-0x410e03cdb445fe78,
-0x3bfd36a6e9c47039,
-0xe3c2aa9e2a2e0b77,
-0x99319ff577af8536,
-0xfdb93e571f9893a7,
-0x874a0b3c42191de6,
-0x0,
-0xb33f7074d9b6e3fe,
-0x2adb64d29a93ef96,
-0x99e414a643250c68,
-0x59dab92a69394e60,
-0xeae5c95eb08fad9e,
-0x7301ddf8f3aaa1f6,
-0xc03ead8c2a1c4208,
-0x3c8004790328459c,
-0x8fbf740dda9ea662,
-0x165b60ab99bbaa0a,
-0xa56410df400d49f4,
-0x655abd536a110bfc,
-0xd665cd27b3a7e802,
-0x4f81d981f082e46a,
-0xfcbea9f529340794,
-0x0,
-0xadcb0001cdaa3d05,
-0x9bb38fd76d5e0c0b,
-0x36788fd6a0f4310e,
-0xabcadd426cb54b4d,
-0x601dd43a11f7648,
-0x3079529501eb4746,
-0x9db25294cc417a43,
-0xf042a8f93e8a48b9,
-0x5d89a8f8f32075bc,
-0x6bf1272e53d444b2,
-0xc63a272f9e7e79b7,
-0x5b8875bb523f03f4,
-0xf64375ba9f953ef1,
-0xc03bfa6c3f610fff,
-0x6df0fa6df2cb32fa,
-0x0,
-0x47b25aab146986f6,
-0xe750955be42931a1,
-0xa0e2cff0f040b757,
-0x9bf1d4a1535a0d17,
-0xdc438e0a47338be1,
-0x7ca141fab7733cb6,
-0x3b131b51a31aba40,
-0x91564f9a406d933c,
-0xd6e41531540415ca,
-0x7606dac1a444a29d,
-0x31b4806ab02d246b,
-0xaa79b3b13379e2b,
-0x4d15c190075e18dd,
-0xedf70e60f71eaf8a,
-0xaa4554cbe377297c,
-0x0,
-0xded3254b42d33aaa,
-0xbd1f32c59e84e45d,
-0x63cc178edc57def7,
-0xfa018660e3165396,
-0x24d2a32ba1c5693c,
-0x471eb4a57d92b7cb,
-0x99cd91ee3f418d61,
-0xa2f911a00f5baa7b,
-0x7c2a34eb4d8890d1,
-0x1fe6236591df4e26,
-0xc135062ed30c748c,
-0x58f897c0ec4df9ed,
-0x862bb28bae9ec347,
-0xe5e7a50572c91db0,
-0x3b34804e301a271a,
-0x0,
-0xe958695bc8926acd,
-0xc8c10606a8ec8d6b,
-0x21996f5d607ee7a6,
-0x8e6cfef54b2e9ac6,
-0x673497ae83bcf00b,
-0x46adf8f3e3c217ad,
-0xaff591a82b507d60,
-0x88007d210e507cf4,
-0x6158147ac6c21639,
-0x40c17b27a6bcf19f,
-0xa999127c6e2e9b52,
-0x66c83d4457ee632,
-0xef34ea8f8dec8cff,
-0xcead85d2ed926b59,
-0x27f5ec8925000194,
-0x0,
-0x17a89b9796a48397,
-0x1bdd636a99f218be,
-0xc75f8fd0f569b29,
-0x7cb821d83481a449,
-0x6b10ba4fa22527de,
-0x676542b2ad73bcf7,
-0x70cdd9253bd73f60,
-0xff39584957728d46,
-0xe891c3dec1d60ed1,
-0xe4e43b23ce8095f8,
-0xf34ca0b45824166f,
-0x8381799163f3290f,
-0x9429e206f557aa98,
-0x985c1afbfa0131b1,
-0x8ff4816c6ca5b226,
-0x0,
-0x9cd7c0f7b4d02de7,
-0x779fca946b676edb,
-0xeb480a63dfb7433c,
-0x5235a7728b715838,
-0xcee267853fa175df,
-0x25aa6de6e01636e3,
-0xb97dad1154c61b04,
-0x70ef0482c08984a5,
-0xec38c4757459a942,
-0x770ce16abeeea7e,
-0x9ba70ee11f3ec799,
-0x22daa3f04bf8dc9d,
-0xbe0d6307ff28f17a,
-0x55456964209fb246,
-0xc992a993944f9fa1,
-0x0,
-0xbb1c3dbfe2b5150b,
-0xee767356051fe0e1,
-0x556a4ee9e7aaf5ea,
-0x1b5c98d75cc93fe8,
-0xa040a568be7c2ae3,
-0xf52aeb8159d6df09,
-0x4e36d63ebb63ca02,
-0x4c25ee1fb1c8ceb6,
-0xf739d3a0537ddbbd,
-0xa2539d49b4d72e57,
-0x194fa0f656623b5c,
-0x577976c8ed01f15e,
-0xec654b770fb4e455,
-0xb90f059ee81e11bf,
-0x21338210aab04b4,
-0x0,
-0xb7310079067f9e51,
-0x4be2a5ae359e2594,
-0xfcd3a5d733e1bbc5,
-0xfe86864026631c3,
-0xb8d9681d0419af92,
-0x440acdca37f81457,
-0xf33bcdb331878a06,
-0x5b4cd59958434683,
-0xec7dd5e05e3cd8d2,
-0x10ae70376ddd6317,
-0xa79f704e6ba2fd46,
-0x54a4bdfd5a257740,
-0xe395bd845c5ae911,
-0x1f4618536fbb52d4,
-0xa877182a69c4cc85,
-0x0,
-0xe550b2539a848707,
-0x6e50d13b6a7a5997,
-0x8b006368f0fede90,
-0x7fd8fb00a5aef99a,
-0x9a8849533f2a7e9d,
-0x11882a3bcfd4a00d,
-0xf4d898685550270a,
-0xcdbd262ac16e806b,
-0x28ed94795bea076c,
-0xa3edf711ab14d9fc,
-0x46bd454231905efb,
-0xb265dd2a64c079f1,
-0x57356f79fe44fef6,
-0xdc350c110eba2066,
-0x3965be42943ea761,
-0x0,
-0xc021427b4f7646e0,
-0xd7f262605a9bcdd0,
-0x17d3201b15ed8b30,
-0xb046630a7efeddc,
-0xcb25244be899ab3c,
-0xdcf60450fd74200c,
-0x1cd7462bb20266ec,
-0xa869f3dfcbe24fab,
-0x6848b1a48494094b,
-0x7f9b91bf9179827b,
-0xbfbad3c4de0fc49b,
-0xa36d95ef6c0da277,
-0x634cd794237be497,
-0x749ff78f36966fa7,
-0xb4beb5f479e02947,
-0x0,
-0xa00150323be9b1de,
-0x1294d8724ae3d0d,
-0xa1281db51f478cd3,
-0x4ab517f07f03a4b1,
-0xeab447c244ea156f,
-0x4b9c5a775bad99bc,
-0xeb9d0a4560442862,
-0xfdc5af3bb370e266,
-0x5dc4ff09889953b8,
-0xfcece2bc97dedf6b,
-0x5cedb28eac376eb5,
-0xb770b8cbcc7346d7,
-0x1771e8f9f79af709,
-0xb659f54ce8dd7bda,
-0x1658a57ed334ca04,
-0x0,
-0x2aff63efa8285238,
-0xfba0ace42227357a,
-0xd15fcf0b8a0f6742,
-0xc208107e1c3e5ac1,
-0xe8f77391b41608f9,
-0x39a8bc9a3e196fbb,
-0x1357df7596313d83,
-0xb2dbb5cb68d0dc74,
-0x9824d624c0f88e4c,
-0x497b192f4af7e90e,
-0x63847ac0e2dfbb36,
-0x70d3a5b574ee86b5,
-0x5a2cc65adcc6d48d,
-0x8b73095156c9b3cf,
-0xa18c6abefee1e1f7,
-};
-
-
-
-uint64_t i_beta_mul_32_bm4r [(64/4)*16*2] __attribute__((aligned(32))) = {
-0x100c7c6c7c60100,0x405c2c3c2c30405, 0x100c7c6c7c60100,0x405c2c3c2c30405,
-0x9d6863960bfef500,0xfb0e05f06d989366, 0x9d6863960bfef500,0xfb0e05f06d989366,
-0xe1e15e5ebfbf0000,0xa0a01f1ffefe4141, 0xe1e15e5ebfbf0000,0xa0a01f1ffefe4141,
-0x44ae6288cc26ea00,0x45af6389cd27eb01, 0x44ae6288cc26ea00,0x45af6389cd27eb01,
-0xa5a5e4e441410000,0xe5e5a4a401014040, 0xa5a5e4e441410000,0xe5e5a4a401014040,
-0x1a1598978d820f00,0xa5aa2728323db0bf, 0x1a1598978d820f00,0xa5aa2728323db0bf,
-0x7e7e060678780000,0xaeaed6d6a8a8d0d0, 0x7e7e060678780000,0xaeaed6d6a8a8d0d0,
-0xd44337a074e39700,0x6afd891eca5d29be, 0xd44337a074e39700,0x6afd891eca5d29be,
-0xe9e963638a8a0000,0x80800a0ae3e36969, 0xe9e963638a8a0000,0x80800a0ae3e36969,
-0xc46115b571d4a00,0x2f653278743e6923, 0xc46115b571d4a00,0x2f653278743e6923,
-0xc7c7dcdc1b1b0000,0xe3e3f8f83f3f2424, 0xc7c7dcdc1b1b0000,0xe3e3f8f83f3f2424,
-0xf41f678c7893eb00,0x4ca7df34c02b53b8, 0xf41f678c7893eb00,0x4ca7df34c02b53b8,
-0xc0c0565696960000,0xf3f36565a5a53333, 0xc0c0565696960000,0xf3f36565a5a53333,
-0x3b2bafbf84941000,0xd9c94d5d6676f2e2, 0x3b2bafbf84941000,0xd9c94d5d6676f2e2,
-0xf5f5fdfd08080000,0x82828a8a7f7f7777, 0xf5f5fdfd08080000,0x82828a8a7f7f7777,
-0x1fce83524d9cd100,0xa3723feef1206dbc, 0x1fce83524d9cd100,0xa3723feef1206dbc,
-0x4e0f9edf91d04100,0xe6a736773978e9a8, 0x4e0f9edf91d04100,0xe6a736773978e9a8,
-0x8f69e606896fe00,0x946a02fcf40a629c, 0x8f69e606896fe00,0x946a02fcf40a629c,
-0x7bf5e36d16988e00,0x1d93850b70fee866, 0x7bf5e36d16988e00,0x1d93850b70fee866,
-0x42a1ad4e0cefe300,0x7e4e80b49aaa645, 0x42a1ad4e0cefe300,0x7e4e80b49aaa645,
-0xea6b5cdd37b68100,0x1998af2ec44572f3, 0xea6b5cdd37b68100,0x1998af2ec44572f3,
-0x1caa8f392593b600,0x3482a7110dbb9e28, 0x1caa8f392593b600,0x3482a7110dbb9e28,
-0xc39ef6ab68355d00,0x421f772ae9b4dc81, 0xc39ef6ab68355d00,0x421f772ae9b4dc81,
-0x2af3b069439ad900,0x29f0b36a4099da03, 0x2af3b069439ad900,0x29f0b36a4099da03,
-0x3853f19aa2c96b00,0x3c57f59ea6cd6f04, 0x3853f19aa2c96b00,0x3c57f59ea6cd6f04,
-0x8cf85e2aa6d27400,0xf5812753dfab0d79, 0x8cf85e2aa6d27400,0xf5812753dfab0d79,
-0x9ca9083da1943500,0xb3e9faa3603a297, 0x9ca9083da1943500,0xb3e9faa3603a297,
-0xadddc9b914647000,0xa9d9cdbd10607404, 0xadddc9b914647000,0xa9d9cdbd10607404,
-0x3fcc44b7887bf300,0x4ab931c2fd0e8675, 0x3fcc44b7887bf300,0x4ab931c2fd0e8675,
-0x3e01e5dae4db3f00,0xbe81655a645bbf80, 0x3e01e5dae4db3f00,0xbe81655a645bbf80,
-0xd8a2c6bc641e7a00,0x87fd99e33b41255f, 0xd8a2c6bc641e7a00,0x87fd99e33b41255f,
-0xc073ea59992ab300,0xfc4fd665a5168f3c, 0xc073ea59992ab300,0xfc4fd665a5168f3c,
-0x4346484d0e0b0500,0xfafff1f4b7b2bcb9, 0x4346484d0e0b0500,0xfafff1f4b7b2bcb9,
-0x40b6e11757a1f600,0x7c8add2b6b9dca3c, 0x40b6e11757a1f600,0x7c8add2b6b9dca3c,
-0x7a47764b310c3d00,0x320f3e0379447548, 0x7a47764b310c3d00,0x320f3e0379447548,
-0xba3c8b0db7318600,0x29af189e24a21593, 0xba3c8b0db7318600,0x29af189e24a21593,
-0x41eb1fb5f45eaa00,0xcb61953f7ed4208a, 0x41eb1fb5f45eaa00,0xcb61953f7ed4208a,
-0x1a73335a40296900,0x771e5e372d44046d, 0x1a73335a40296900,0x771e5e372d44046d,
-0xcc01a16ca06dcd00,0xf23f9f529e53f33e, 0xcc01a16ca06dcd00,0xf23f9f529e53f33e,
-0xa3b74753f0e41400,0xe3f70713b0a45440, 0xa3b74753f0e41400,0xe3f70713b0a45440,
-0x94954342d6d70100,0x6d6cbabb2f2ef8f9, 0x94954342d6d70100,0x6d6cbabb2f2ef8f9,
-0x51fa0aa1f05bab00,0xcb60903b6ac1319a, 0x51fa0aa1f05bab00,0xcb60903b6ac1319a,
-0x5252dddd8f8f0000,0xfafa75752727a8a8, 0x5252dddd8f8f0000,0xfafa75752727a8a8,
-0x1b418ed4cf955a00,0x540ec19b80da154f, 0x1b418ed4cf955a00,0x540ec19b80da154f,
-0xb27901ca78b3cb00,0xf03b43883af18942, 0xb27901ca78b3cb00,0xf03b43883af18942,
-0x13a143f1e250b200,0x45f715a7b406e456, 0x13a143f1e250b200,0x45f715a7b406e456,
-0x9d3006ab369bad00,0x6dc0f65bc66b5df0, 0x9d3006ab369bad00,0x6dc0f65bc66b5df0,
-0x3b7cdc9ba0e74700,0xaaed4d0a3176d691, 0x3b7cdc9ba0e74700,0xaaed4d0a3176d691,
-0x61cb3c96f75daa00,0x1ab047ed8c26d17b, 0x61cb3c96f75daa00,0x1ab047ed8c26d17b,
-0x60ad0bc6a66bcd00,0x9459ff32529f39f4, 0x60ad0bc6a66bcd00,0x9459ff32529f39f4,
-0x8db76953dee43a00,0x271dc3f9744e90aa, 0x8db76953dee43a00,0x271dc3f9744e90aa,
-0x7d17f09ae78d6a00,0x16b8ce69bf1167c, 0x7d17f09ae78d6a00,0x16b8ce69bf1167c,
-0x4192c5165784d300,0x1ac99e4d0cdf885b, 0x4192c5165784d300,0x1ac99e4d0cdf885b,
-0x50c2bc2e7eec9200,0x92ec7e2ebcc250, 0x50c2bc2e7eec9200,0x92ec7e2ebcc250,
-0x3f7da1e3dc9e4200,0x3072aeecd3914d0f, 0x3f7da1e3dc9e4200,0x3072aeecd3914d0f,
-0x2be3834b60a8c800,0x25ed8d456ea6c60e, 0x2be3834b60a8c800,0x25ed8d456ea6c60e,
-0xeea52b608ec54b00,0x4e058bc02e65eba0, 0xeea52b608ec54b00,0x4e058bc02e65eba0,
-0xa8f3aef55d065b00,0x89d28fd47c277a21, 0xa8f3aef55d065b00,0x89d28fd47c277a21,
-0x91b4a38617322500,0x80a5b29706233411, 0x91b4a38617322500,0x80a5b29706233411,
-0x91f897fe6f066900,0xec85ea83127b147d, 0x91f897fe6f066900,0xec85ea83127b147d,
-0xcd1ed201cc1fd300,0x34e72bf835e62af9, 0xcd1ed201cc1fd300,0x34e72bf835e62af9,
-0xf5ad346c99c15800,0xf5ad346c99c15800, 0xf5ad346c99c15800,0xf5ad346c99c15800,
-0x994724fa63bdde00,0x3be58658c11f7ca2, 0x994724fa63bdde00,0x3be58658c11f7ca2,
-0xaf46678e21c8e900,0x27ceef06a9406188, 0xaf46678e21c8e900,0x27ceef06a9406188,
-0x60f7de4929be9700,0x26b1980f6ff8d146, 0x60f7de4929be9700,0x26b1980f6ff8d146,
-0x4e3df383cdbe700,0xa1467a9d997e42a5, 0x4e3df383cdbe700,0xa1467a9d997e42a5,
-0x3fbc27a49b188300,0xb231aa2916950e8d, 0x3fbc27a49b188300,0xb231aa2916950e8d,
-0x1b367558436e2d00,0x9fb2f1dcc7eaa984, 0x1b367558436e2d00,0x9fb2f1dcc7eaa984,
-0xd773258156f2a400,0xa50157f32480d672, 0xd773258156f2a400,0xa50157f32480d672,
-0xc616a171b767d000,0x4f9f28f83eee5989, 0xc616a171b767d000,0x4f9f28f83eee5989,
-0x3bada2340f999600,0x6cfaf56358cec157, 0x3bada2340f999600,0x6cfaf56358cec157,
-0x54e03f8bdf6bb400,0x9420ff4b1fab74c0, 0x54e03f8bdf6bb400,0x9420ff4b1fab74c0,
-0x25b24fd8fd6a9700,0x6cfb0691b423de49, 0x25b24fd8fd6a9700,0x6cfb0691b423de49,
-0x11e685726394f700,0x936407f0e1167582, 0x11e685726394f700,0x936407f0e1167582,
-0xd942ba21f8639b00,0x811ae279a03bc358, 0xd942ba21f8639b00,0x811ae279a03bc358,
-0xad6d67a70acac000,0xa96963a30ecec404, 0xad6d67a70acac000,0xa96963a30ecec404,
-0xcd6510b875dda800,0xf45c29814ce49139, 0xcd6510b875dda800,0xf45c29814ce49139,
-0x7daae235489fd700,0x92450ddaa77038ef, 0x7daae235489fd700,0x92450ddaa77038ef,
-0x70676b7c0c1b1700,0x8f989483f3e4e8ff, 0x70676b7c0c1b1700,0x8f989483f3e4e8ff,
-0xb925ce52eb779c00,0xc955be229b07ec70, 0xb925ce52eb779c00,0xc955be229b07ec70,
-0x209e3e8eae10b00,0xb4bf555e5c57bdb6, 0x209e3e8eae10b00,0xb4bf555e5c57bdb6,
-0x65792c3c5945100,0x85d411404617d283, 0x65792c3c5945100,0x85d411404617d283,
-0xcadf2a3ff5e01500,0x411e4f13b2edbce, 0xcadf2a3ff5e01500,0x411e4f13b2edbce,
-0x8a14af31bb259e00,0xcc52e977fd63d846, 0x8a14af31bb259e00,0xcc52e977fd63d846,
-0x63d67cc9aa1fb500,0xab1eb40162d77dc8, 0x63d67cc9aa1fb500,0xab1eb40162d77dc8,
-0x87f81966e19e7f00,0xc4bb5a25a2dd3c43, 0x87f81966e19e7f00,0xc4bb5a25a2dd3c43,
-0xbb59be5ce705e200,0xae80fed56b453b1, 0xbb59be5ce705e200,0xae80fed56b453b1,
-0x3137040233350600,0x696f5c5a6b6d5e58, 0x3137040233350600,0x696f5c5a6b6d5e58,
-0x3e8168d7e956bf00,0x219e77c8f649a01f, 0x3e8168d7e956bf00,0x219e77c8f649a01f,
-0xb3ca1d64d7ae7900,0x2a5384fd4e37e099, 0xb3ca1d64d7ae7900,0x2a5384fd4e37e099,
-0xd6eba5984e733d00,0x38054b76a09dd3ee, 0xd6eba5984e733d00,0x38054b76a09dd3ee,
-0xcdcd6868a5a50000,0x1818bdbd7070d5d5, 0xcdcd6868a5a50000,0x1818bdbd7070d5d5,
-0x362a405c6a761c00,0x130f65794f533925, 0x362a405c6a761c00,0x130f65794f533925,
-0x3b0ad9e8d3e23100,0x774695a49fae7d4c, 0x3b0ad9e8d3e23100,0x774695a49fae7d4c,
-0x4ef5a01b55eebb00,0x2b9ec5719a2f74c, 0x4ef5a01b55eebb00,0x2b9ec5719a2f74c,
-0xf344b80ffc4bb700,0xa81fe354a710ec5b, 0xf344b80ffc4bb700,0xa81fe354a710ec5b,
-0xa0d9d9a90970700,0x6166f6f1fbfc6c6b, 0xa0d9d9a90970700,0x6166f6f1fbfc6c6b,
-0xec0c3cdc30d0e000,0x47a797779b7b4bab, 0xec0c3cdc30d0e000,0x47a797779b7b4bab,
-0x27a07ef9de598700,0xa720fe795ed90780, 0x27a07ef9de598700,0xa720fe795ed90780,
-0x6620abed8bcd4600,0x296fe4a2c482094f, 0x6620abed8bcd4600,0x296fe4a2c482094f,
-0x50d42aaefe7a8400,0x3eba44c09014ea6e, 0x50d42aaefe7a8400,0x3eba44c09014ea6e,
-0x27499efed9b7600,0xe0967b0d0f7994e2, 0x27499efed9b7600,0xe0967b0d0f7994e2,
-0x55cf3fa5f06a9a00,0x940efe6431ab5bc1, 0x55cf3fa5f06a9a00,0x940efe6431ab5bc1,
-0xb2fde8a7155a4f00,0x7936236cde9184cb, 0xb2fde8a7155a4f00,0x7936236cde9184cb,
-0x683b5300683b5300,0x4211792a4211792a, 0x683b5300683b5300,0x4211792a4211792a,
-0x2b504b301b607b00,0xf48f94efc4bfa4df, 0x2b504b301b607b00,0xf48f94efc4bfa4df,
-0x982a49fb63d1b200,0xbe0c6fdd45f79426, 0x982a49fb63d1b200,0xbe0c6fdd45f79426,
-0x4604246620624200,0xb5f7d795d391b1f3, 0x4604246620624200,0xb5f7d795d391b1f3,
-0xd88888d800505000,0x65353565bdededbd, 0xd88888d800505000,0x65353565bdededbd,
-0xd7f62504d3f22100,0xbe9f4c6dba9b4869, 0xd7f62504d3f22100,0xbe9f4c6dba9b4869,
-0xf4119a7f8b6ee500,0x39dc57b246a328cd, 0xf4119a7f8b6ee500,0x39dc57b246a328cd,
-0x1cdccb0b17d7c000,0xb47463a3bf7f68a8, 0x1cdccb0b17d7c000,0xb47463a3bf7f68a8,
-0x62bc6fb1d30dde00,0x4da09d7b56bb866, 0x62bc6fb1d30dde00,0x4da09d7b56bb866,
-0x83bbf9c1427a3800,0xf7cf8db5360e4c74, 0x83bbf9c1427a3800,0xf7cf8db5360e4c74,
-0x289915a48c3db100,0xca7bf7466edf53e2, 0x289915a48c3db100,0xca7bf7466edf53e2,
-0x3d6f085a67355200,0xe1b3d486bbe98edc, 0x3d6f085a67355200,0xe1b3d486bbe98edc,
-0x44adea0347aee900,0x34dd9a7337de9970, 0x44adea0347aee900,0x34dd9a7337de9970,
-0x3119163e0f272800,0xe1c9c6eedff7f8d0, 0x3119163e0f272800,0xe1c9c6eedff7f8d0,
-0x605b447f1f243b00,0xd3e8f7ccac9788b3, 0x605b447f1f243b00,0xd3e8f7ccac9788b3,
-0x963eb41c8a22a800,0xfe56dc74e24ac068, 0x963eb41c8a22a800,0xfe56dc74e24ac068,
-0x4577c2f0b5873200,0x7e4cf9cb8ebc093b, 0x4577c2f0b5873200,0x7e4cf9cb8ebc093b,
-0x759a917e0be4ef00,0xbe515ab5c02f24cb, 0x759a917e0be4ef00,0xbe515ab5c02f24cb,
-0xa5a47171d4d5000,0xa5f5e8b8b2e2ffaf, 0xa5a47171d4d5000,0xa5f5e8b8b2e2ffaf,
-0xdfbc7310cfac6300,0x6a09c6a57a19d6b5, 0xdfbc7310cfac6300,0x6a09c6a57a19d6b5,
-0x9d9cb4b528290100,0x58597170edecc4c5, 0x9d9cb4b528290100,0x58597170edecc4c5,
-0x57a8f7085fa0ff00,0x8c732cd3847b24db, 0x57a8f7085fa0ff00,0x8c732cd3847b24db,
-0xeb4bea4aa101a000,0x16b617b75cfc5dfd, 0xeb4bea4aa101a000,0x16b617b75cfc5dfd,
-0x1339e8c2d1fb2a00,0xa18b5a70634998b2, 0x1339e8c2d1fb2a00,0xa18b5a70634998b2,
-};
-
-
-uint64_t beta_mul_32_bm4r [(64/4)*16*2] __attribute__((aligned(32))) = {
-0x9796d3d245440100,0x8485c0c156571213, 0x9796d3d245440100,0x8485c0c156571213,
-0xe9b9e8b851015000,0x6d3d6c3cd585d484, 0xe9b9e8b851015000,0x6d3d6c3cd585d484,
-0xd6d6b4b462620000,0x74741616c0c0a2a2, 0xd6d6b4b462620000,0x74741616c0c0a2a2,
-0x679fb1492ed6f800,0xbb436d95f20a24dc, 0x679fb1492ed6f800,0xbb436d95f20a24dc,
-0x191914140d0d0000,0x6a6a67677e7e7373, 0x191914140d0d0000,0x6a6a67677e7e7373,
-0xd36077c417a4b300,0x5ae9fe4d9e2d3a89, 0xd36077c417a4b300,0x5ae9fe4d9e2d3a89,
-0x6363ecec8f8f0000,0xf4f47b7b18189797, 0x6363ecec8f8f0000,0xf4f47b7b18189797,
-0x255189fdd8ac7400,0x483ce490b5c1196d, 0x255189fdd8ac7400,0x483ce490b5c1196d,
-0x9191e6e677770000,0x52522525b4b4c3c3, 0x9191e6e677770000,0x52522525b4b4c3c3,
-0x4c7b3e0945723700,0x427530074b7c390e, 0x4c7b3e0945723700,0x427530074b7c390e,
-0xaaaa6464cece0000,0x41418f8f2525ebeb, 0xaaaa6464cece0000,0x41418f8f2525ebeb,
-0x813e6dd253ecbf00,0xfd4211ae2f90c37c, 0x813e6dd253ecbf00,0xfd4211ae2f90c37c,
-0x3f3f686857570000,0xd2d28585babaeded, 0x3f3f686857570000,0xd2d28585babaeded,
-0xe702a643a441e500,0x7d983cd93edb7f9a, 0xe702a643a441e500,0x7d983cd93edb7f9a,
-0x5b5bb6b6eded0000,0xc7c72a2a71719c9c, 0x5b5bb6b6eded0000,0xc7c72a2a71719c9c,
-0xb7e31d49feaa5400,0xd98d732790c43a6e, 0xb7e31d49feaa5400,0xd98d732790c43a6e,
-0x28ea02c2ea28c00,0xd15d73fffd715fd3, 0x28ea02c2ea28c00,0xd15d73fffd715fd3,
-0x3ff772ba854dc800,0x30f87db58a42c70f, 0x3ff772ba854dc800,0x30f87db58a42c70f,
-0xc7584cd3148b9f00,0x897831cdb4450cf, 0xc7584cd3148b9f00,0x897831cdb4450cf,
-0x6ed065dbb50bbe00,0x7bc570cea01eab15, 0x6ed065dbb50bbe00,0x7bc570cea01eab15,
-0xf10575817084f400,0xe81c6c98699ded19, 0xf10575817084f400,0xe81c6c98699ded19,
-0xd7f80827f0df2f00,0xeac5351acde2123d, 0xd7f80827f0df2f00,0xeac5351acde2123d,
-0x8a1b28b933a29100,0xc35261f07aebd849, 0x8a1b28b933a29100,0xc35261f07aebd849,
-0x5e847fa5fb21da00,0x62b84399c71de63c, 0x5e847fa5fb21da00,0x62b84399c71de63c,
-0xe87745da32ad9f00,0x51cefc638b1426b9, 0xe87745da32ad9f00,0x51cefc638b1426b9,
-0x2c37011a362d1b00,0x8893a5be9289bfa4, 0x2c37011a362d1b00,0x8893a5be9289bfa4,
-0x2dca39def314e700,0x17f003e4c92edd3a, 0x2dca39def314e700,0x17f003e4c92edd3a,
-0x7bcfdd6912a6b400,0x9c283a8ef54153e7, 0x7bcfdd6912a6b400,0x9c283a8ef54153e7,
-0xbdff7e3c81c34200,0x6426a7e5581a9bd9, 0xbdff7e3c81c34200,0x6426a7e5581a9bd9,
-0x2d7e6a3914475300,0x1f4c580b26756132, 0x2d7e6a3914475300,0x1f4c580b26756132,
-0xe60dbb50b65deb00,0xc72c9a71977cca21, 0xe60dbb50b65deb00,0xc72c9a71977cca21,
-0xc88d03468ecb4500,0x286de3a66e2ba5e0, 0xc88d03468ecb4500,0x286de3a66e2ba5e0,
-0x60fad44e2eb49a00,0xfe644ad0b02a049e, 0x60fad44e2eb49a00,0xfe644ad0b02a049e,
-0xce83511cd29f4d00,0x400ddf925c11c38e, 0xce83511cd29f4d00,0x400ddf925c11c38e,
-0xb4b76665d1d20300,0x1310c1c27675a4a7, 0xb4b76665d1d20300,0x1310c1c27675a4a7,
-0x5031f293c3a26100,0x5233f091c1a06302, 0x5031f293c3a26100,0x5233f091c1a06302,
-0x96f69cfc6a0a6000,0x5d3d5737a1c1abcb, 0x96f69cfc6a0a6000,0x5d3d5737a1c1abcb,
-0x87cb105cdb974c00,0x155982ce4905de92, 0x87cb105cdb974c00,0x155982ce4905de92,
-0x8c41ea27ab66cd00,0x569b30fd71bc17da, 0x8c41ea27ab66cd00,0x569b30fd71bc17da,
-0x720bdda4d6af7900,0x30499fe694ed3b42, 0x720bdda4d6af7900,0x30499fe694ed3b42,
-0xf41093778367e400,0xa541c226d236b551, 0xf41093778367e400,0xa541c226d236b551,
-0xf3337cbc4f8fc000,0x12d29d5dae6e21e1, 0xf3337cbc4f8fc000,0x12d29d5dae6e21e1,
-0xf8fa8f8d75770200,0xd2d0a5a75f5d282a, 0xf8fa8f8d75770200,0xd2d0a5a75f5d282a,
-0x548315c29641d700,0x67b026f1a572e433, 0x548315c29641d700,0x67b026f1a572e433,
-0x62974abfdd28f500,0xd326fb0e6c9944b1, 0x62974abfdd28f500,0xd326fb0e6c9944b1,
-0x9b0a54c55ecf9100,0x2fbee071ea7b25b4, 0x9b0a54c55ecf9100,0x2fbee071ea7b25b4,
-0x55e5ad1d48f8b000,0x4cfcb40451e1a919, 0x55e5ad1d48f8b000,0x4cfcb40451e1a919,
-0xc127e90fce28e600,0x8d6ba5438264aa4c, 0xc127e90fce28e600,0x8d6ba5438264aa4c,
-0x47b146b6f107f00,0xeb94fb8480ff90ef, 0x47b146b6f107f00,0xeb94fb8480ff90ef,
-0x4e7b1326685d3500,0xe6d3bb8ec0f59da8, 0x4e7b1326685d3500,0xe6d3bb8ec0f59da8,
-0x7b750c0279770e00,0x737d040a717f0608, 0x7b750c0279770e00,0x737d040a717f0608,
-0x2e18380e20163600,0xcff9d9efc1f7d7e1, 0x2e18380e20163600,0xcff9d9efc1f7d7e1,
-0x4a592b3872611300,0x9784f6e5afbccedd, 0x4a592b3872611300,0x9784f6e5afbccedd,
-0x6344654221062700,0x6c4b6a4d2e09280f, 0x6344654221062700,0x6c4b6a4d2e09280f,
-0x74787874000c0c00,0xf7fbfbf7838f8f83, 0x74787874000c0c00,0xf7fbfbf7838f8f83,
-0xebdb8bbb50603000,0x51613101eada8aba, 0xebdb8bbb50603000,0x51613101eada8aba,
-0x73f75adead298400,0x8400ad295ade73f7, 0x73f75adead298400,0x8400ad295ade73f7,
-0xda3f769349ace500,0x9c7930d50feaa346, 0xda3f769349ace500,0x9c7930d50feaa346,
-0xb59c80a91c352900,0xe8c1ddf44168745d, 0xb59c80a91c352900,0xe8c1ddf44168745d,
-0xda328e66bc54e800,0x38d06c845eb60ae2, 0xda328e66bc54e800,0x38d06c845eb60ae2,
-0x30ab6ff4c45f9b00,0xda41851e2eb571ea, 0x30ab6ff4c45f9b00,0xda41851e2eb571ea,
-0x305a4b21117b6a00,0x600a1b71412b3a50, 0x305a4b21117b6a00,0x600a1b71412b3a50,
-0x2830190129311800,0x425a736b435b726a, 0x2830190129311800,0x425a736b435b726a,
-0x79cafa493083b300,0x843707b4cd7e4efd, 0x79cafa493083b300,0x843707b4cd7e4efd,
-0x586cb185dde93400,0xa7934e7a2216cbff, 0x586cb185dde93400,0xa7934e7a2216cbff,
-0x2b3e8792b9ac1500,0x9c8930250e1ba2b7, 0x2b3e8792b9ac1500,0x9c8930250e1ba2b7,
-0x702ffca3d38c5f00,0x4619ca95e5ba6936, 0x702ffca3d38c5f00,0x4619ca95e5ba6936,
-0xed9c7908e5947100,0x4736d3a24f3edbaa, 0xed9c7908e5947100,0x4736d3a24f3edbaa,
-0x3a34bbb58f810e00,0xbcb23d3309078886, 0x3a34bbb58f810e00,0xbcb23d3309078886,
-0x3b45f688b3cd7e00,0xf6883b457e00b3cd, 0x3b45f688b3cd7e00,0xf6883b457e00b3cd,
-0x1bd675b8a36ecd00,0xc30ead607bb615d8, 0x1bd675b8a36ecd00,0xc30ead607bb615d8,
-0xc1f4deeb2a1f3500,0xc1f4deeb2a1f3500, 0xc1f4deeb2a1f3500,0xc1f4deeb2a1f3500,
-0xda9594db014e4f00,0x1d52531cc68988c7, 0xda9594db014e4f00,0x1d52531cc68988c7,
-0x97aa89b4231e3d00,0x54694a77e0ddfec3, 0x97aa89b4231e3d00,0x54694a77e0ddfec3,
-0x80904c5cdccc1000,0xeafa2636b6a67a6a, 0x80904c5cdccc1000,0xeafa2636b6a67a6a,
-0x22c13eddff1ce300,0xcc2fd03311f20dee, 0x22c13eddff1ce300,0xcc2fd03311f20dee,
-0xe0435bf818bba300,0x63c0d87b9b382083, 0xe0435bf818bba300,0x63c0d87b9b382083,
-0x77d92e80f759ae00,0x8a651ff8826d17f, 0x77d92e80f759ae00,0x8a651ff8826d17f,
-0xa7f0184fe8bf5700,0x4215fdaa0d5ab2e5, 0xa7f0184fe8bf5700,0x4215fdaa0d5ab2e5,
-0x238ff65a79d5ac00,0x76daa30f2c80f955, 0x238ff65a79d5ac00,0x76daa30f2c80f955,
-0xa3943c0ba89f3700,0xba8d2512b1862e19, 0xa3943c0ba89f3700,0xba8d2512b1862e19,
-0x7992a54e37dceb00,0xea0136dda44f7893, 0x7992a54e37dceb00,0xea0136dda44f7893,
-0x205e2e50700e7e00,0x3d43334d6d13631d, 0x205e2e50700e7e00,0x3d43334d6d13631d,
-0xe0ce5a7494ba2e00,0x8ba5311fffd1456b, 0xe0ce5a7494ba2e00,0x8ba5311fffd1456b,
-0x2ece81614fafe000,0x1dfdb2527c9cd333, 0x2ece81614fafe000,0x1dfdb2527c9cd333,
-0xf3f7afab585c0400,0xc2c69e9a696d3531, 0xf3f7afab585c0400,0xc2c69e9a696d3531,
-0x4d73615f122c3e00,0x8fb1a39dd0eefcc2, 0x4d73615f122c3e00,0x8fb1a39dd0eefcc2,
-0x716acfd4a5be1b00,0x5348edf6879c3922, 0x716acfd4a5be1b00,0x5348edf6879c3922,
-0x487d3500487d3500,0xc0f5bd88c0f5bd88, 0x487d3500487d3500,0xc0f5bd88c0f5bd88,
-0xba39c447fd7e8300,0x2dae53d06ae91497, 0xba39c447fd7e8300,0x2dae53d06ae91497,
-0x3ee84197a97fd600,0xd701a87e40963fe9, 0x3ee84197a97fd600,0xd701a87e40963fe9,
-0x98fa482ab2d06200,0x553785e77f1dafcd, 0x98fa482ab2d06200,0x553785e77f1dafcd,
-0xd5ea93ac79463f00,0x81bec7f82d126b54, 0xd5ea93ac79463f00,0x81bec7f82d126b54,
-0x23dfb844679bfc00,0xcf0976b48b4d32f, 0x23dfb844679bfc00,0xcf0976b48b4d32f,
-0xecb6b0ea065c5a00,0x7923257f93c9cf95, 0xecb6b0ea065c5a00,0x7923257f93c9cf95,
-0xa0e6480eaee84600,0xe9af0147e7a10f49, 0xa0e6480eaee84600,0xe9af0147e7a10f49,
-0xa1a2191abbb80300,0xd5d66d6ecfcc7774, 0xa1a2191abbb80300,0xd5d66d6ecfcc7774,
-0x9672a444d236e00,0xd8b6fb959cf2bfd1, 0x9672a444d236e00,0xd8b6fb959cf2bfd1,
-0x20d8a25a7a82f800,0x3fb817959a1db23, 0x20d8a25a7a82f800,0x3fb817959a1db23,
-0x48f6803e76c8be00,0x2e90e65810aed866, 0x48f6803e76c8be00,0x2e90e65810aed866,
-0xffebd3c7382c1400,0x77635b4fb0a49c88, 0xffebd3c7382c1400,0x77635b4fb0a49c88,
-0xfce2d5cb37291e00,0x4957607e829cabb5, 0xfce2d5cb37291e00,0x4957607e829cabb5,
-0xa7ff93cb6c345800,0xa9f19dc5623a560e, 0xa7ff93cb6c345800,0xa9f19dc5623a560e,
-0xb7059c2e992bb200,0x74c65fed5ae871c3, 0xb7059c2e992bb200,0x74c65fed5ae871c3,
-0xa1095ef657ffa800,0x5adfa52f35b0ca4, 0xa1095ef657ffa800,0x5adfa52f35b0ca4,
-0x31d8a34a7b92e900,0xbd542fc6f71e658c, 0x31d8a34a7b92e900,0xbd542fc6f71e658c,
-0x97a6fdcc5b6a3100,0x29184372e5d48fbe, 0x97a6fdcc5b6a3100,0x29184372e5d48fbe,
-0x168869f7e17f9e00,0x801eff6177e90896, 0x168869f7e17f9e00,0x801eff6177e90896,
-0xbbdf7216adc96400,0xcaae0367dcb81571, 0xbbdf7216adc96400,0xcaae0367dcb81571,
-0xa50909a500acac00,0xff5353ff5af6f65a, 0xa50909a500acac00,0xff5353ff5af6f65a,
-0x5ce4ff471ba3b800,0x7bfa41c40f8e35b, 0x5ce4ff471ba3b800,0x7bfa41c40f8e35b,
-0x7531d494e1a5400,0x4d19570304501e4a, 0x7531d494e1a5400,0x4d19570304501e4a,
-0xd97ccf6ab316a500,0xeb4efd5881249732, 0xd97ccf6ab316a500,0xeb4efd5881249732,
-0x47f0f34403b4b700,0xbbcbf084ff8fb4c, 0x47f0f34403b4b700,0xbbcbf084ff8fb4c,
-0x7d77c7cdb0ba0a00,0x7379c9c3beb4040e, 0x7d77c7cdb0ba0a00,0x7379c9c3beb4040e,
-0xd4331bfc28cfe700,0x30d7ff18cc2b03e4, 0xd4331bfc28cfe700,0x30d7ff18cc2b03e4,
-0xf2546fc93b9da600,0xf3556ec83a9ca701, 0xf2546fc93b9da600,0xf3556ec83a9ca701,
-0xfc3cb2728e4ec000,0xea2aa4649858d616, 0xfc3cb2728e4ec000,0xea2aa4649858d616,
-0x1a8882100a989200,0x1f8d87150f9d9705, 0x1a8882100a989200,0x1f8d87150f9d9705,
-0xa2d41365c7b17600,0xb7dbacc6e18dfa9, 0xa2d41365c7b17600,0xb7dbacc6e18dfa9,
-0xa66929e6408fcf00,0xe32c6ca305ca8a45, 0xa66929e6408fcf00,0xe32c6ca305ca8a45,
-0x39a7a739009e9e00,0xbd2323bd841a1a84, 0x39a7a739009e9e00,0xbd2323bd841a1a84,
-0xd20f9f42904ddd00,0xb76afa27f528b865, 0xd20f9f42904ddd00,0xb76afa27f528b865,
-0xd02336c515e6f300,0x5ba8bd4e9e6d788b, 0xd02336c515e6f300,0x5ba8bd4e9e6d788b,
-0x6322632241004100,0x92d392d3b0f1b0f1, 0x6322632241004100,0x92d392d3b0f1b0f1,
-0xcd4035b875f88d00,0xea67129f52dfaa27, 0xcd4035b875f88d00,0xea67129f52dfaa27,
-0xf4f21a1ce8ee0600,0xadab4345b1b75f59, 0xf4f21a1ce8ee0600,0xadab4345b1b75f59,
-0x8d80010c818c0d00,0xb6bb3a37bab7363b, 0x8d80010c818c0d00,0xb6bb3a37bab7363b,
-};
diff --git a/trunc_btfy_tab_64.h b/trunc_btfy_tab_64.h
deleted file mode 100644
index d01a7da..0000000
--- a/trunc_btfy_tab_64.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-Copyright (C) 2017 Ming-Shing Chen
-
-This file is part of BitPolyMul.
-
-BitPolyMul is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-BitPolyMul is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with BitPolyMul. If not, see .
-*/
-
-
-#ifndef _TRUNC_BTFY_TAB_64_H_
-#define _TRUNC_BTFY_TAB_64_H_
-
-#include "stdint.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-extern uint64_t beta_mul_32 [];
-
-extern uint64_t i_beta_mul_32 [];
-
-
-extern uint64_t beta_mul_32_m4r [];
-
-extern uint64_t i_beta_mul_32_m4r [];
-
-
-extern uint64_t beta_mul_32_bm4r [];
-
-extern uint64_t i_beta_mul_32_bm4r [];
-
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif