├── x86 ├── luts.c ├── lwe_original.h ├── makefile ├── lwe.h ├── global.h ├── main.c ├── lwe_original.c └── lwe.c ├── stm32f407-discovery-rlwe ├── core ├── main.bin ├── main.elf ├── unit_test.h ├── stm32_flash.ld ├── svn-commit.tmp ├── speed_test.h ├── random_bits.txt ├── global.c ├── comm.h ├── term_io.h ├── .project ├── code_size.py ├── lwe_arm.h ├── main.c ├── lwe.h ├── stm32f4xx_it.h ├── global.h ├── stm32f4xx_conf.h ├── Makefile ├── .cproject ├── stm32f4xx_it.c ├── term_io.c ├── lwe_arm.c ├── comm.c ├── knuth_yao_asm.S ├── knuth_yao_asm_shuffle.S ├── a.txt ├── speed_test.c ├── unit_test.c ├── system_stm32f4xx.c └── startup_stm32f40xx.s ├── LICENSE └── README.md /x86/luts.c: -------------------------------------------------------------------------------- 1 | #include "luts.h" 2 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruandc/Ring-LWE-Encryption/HEAD/stm32f407-discovery-rlwe/core -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/main.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruandc/Ring-LWE-Encryption/HEAD/stm32f407-discovery-rlwe/main.bin -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/main.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruandc/Ring-LWE-Encryption/HEAD/stm32f407-discovery-rlwe/main.elf -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/unit_test.h: -------------------------------------------------------------------------------- 1 | #ifndef UNIT_TEST_H_ 2 | #define UNIT_TEST_H_ 3 | void perform_unit_tests(); 4 | #endif 5 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/stm32_flash.ld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruandc/Ring-LWE-Encryption/HEAD/stm32f407-discovery-rlwe/stm32_flash.ld -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/svn-commit.tmp: -------------------------------------------------------------------------------- 1 | 2 | --This line, and those below, will be ignored-- 3 | 4 | M .cproject 5 | M .project 6 | M global.h 7 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/speed_test.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPEED_TEST_H_ 2 | #define __SPEED_TEST_H_ 3 | 4 | 5 | #include "global.h" 6 | 7 | void speed_test(); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/random_bits.txt: -------------------------------------------------------------------------------- 1 | Script started on Thu 04 Sep 2014 05:12:43 PM CEST 2 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ exitscreen /dev/ttyUSB0 115200 3 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ exit 4 | exit 5 | 6 | Script done on Thu 04 Sep 2014 05:12:59 PM CEST 7 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/global.c: -------------------------------------------------------------------------------- 1 | #include "stdint.h" 2 | #include "global.h" 3 | #define attribute_fixed_data1 __attribute__((section(".fixed_data1"))); 4 | uint16_t fixed_data1[M] attribute_fixed_data1; 5 | uint16_t fixed_data2[M] attribute_fixed_data1; 6 | uint16_t fixed_data3[M] attribute_fixed_data1; 7 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/comm.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMFUNC 2 | #define _COMMFUNC 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | #include 8 | 9 | void comm_init (void); 10 | int comm_test (void); 11 | void comm_put (unsigned char); 12 | unsigned char comm_get (void); 13 | void USART_puts(USART_TypeDef* USARTx, volatile char *s); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | 19 | #endif 20 | 21 | -------------------------------------------------------------------------------- /x86/lwe_original.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lwe_original.h 3 | * 4 | * Created on: Sep 1, 2014 5 | * Author: rdeclerc 6 | */ 7 | 8 | #ifndef LWE_ORIGINAL_H_ 9 | #define LWE_ORIGINAL_H_ 10 | 11 | #include "global.h" 12 | #include "stdint.h" 13 | //#include "luts.h" 14 | 15 | void fwd_ntt(int a_0[], int a_1[]); 16 | void a_gen( int a_0[], int a_1[]); 17 | //int compare2(int a_0[128],int a_1[128],int large[M]); 18 | int compare2(int a_0[128],int a_1[128],uint16_t large[M]); 19 | 20 | 21 | #endif /* LWE_ORIGINAL_H_ */ 22 | -------------------------------------------------------------------------------- /x86/makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | 3 | CFLAGS= -g -O0 4 | 5 | 6 | LDFLAGS= 7 | 8 | SOURCES=main.c \ 9 | lwe.c \ 10 | lwe_original.c 11 | 12 | OBJECTS1=$(SOURCES:.S=.o) 13 | OBJECTS2=$(OBJECTS1:.s=.o) 14 | OBJECTS=$(OBJECTS2:.c=.o) 15 | EXECUTABLE=LWE 16 | 17 | all: $(SOURCES) $(EXECUTABLE) 18 | 19 | $(EXECUTABLE): $(OBJECTS) 20 | $(CC) $(LDFLAGS) $(OBJECTS) -o $@ 21 | 22 | disassemble: 23 | $(OBJDUMP) -S --disassemble -D $(EXECUTABLE) > $(EXECUTABLE).dump 24 | 25 | clean: 26 | $(RM) $(EXECUTABLE) *.o perf1.dsu 27 | 28 | 29 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/term_io.h: -------------------------------------------------------------------------------- 1 | #ifndef TERM_IO_H_ 2 | #define TERM_IO_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include "comm.h" 10 | 11 | #define xgetc() (char)comm_get() 12 | #define xavail() comm_test() 13 | 14 | int xatoi (char**, long*); 15 | void xputc (char); 16 | void xputs (const char*); 17 | void xitoa (long, int, int); 18 | void xprintf (const char*, ...) __attribute__ ((format (__printf__, 1, 2))); 19 | void put_dump (const uint8_t*, uint32_t ofs, int cnt); 20 | void get_line (char*, int len); 21 | int get_line_r (char*, int len, int *idx); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | #endif /* TERM_IO_H_ */ 28 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | USART_example 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | 14 | 15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 16 | full,incremental, 17 | 18 | 19 | 20 | 21 | 22 | org.eclipse.cdt.core.cnature 23 | org.eclipse.cdt.core.ccnature 24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 26 | 27 | 28 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/code_size.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from subprocess import call 4 | call(["make", "disassemble"]) 5 | 6 | 7 | starts="RLWE_enc_asm","RLWE_dec_asm","coefficient_add_asm","coefficient_mul_asm","coefficient_sub_asm","inv_ntt_asm","fwd_ntt_asm","fwd_ntt_parallel_asm","rearrange_asm","a_gen_asm","r2_gen_asm","encode_message_asm","r1_gen_asm","key_gen_asm","knuth_yao_asm","coefficient_mul_add_asm" 8 | ends="message_gen_asm","RLWE_enc_asm","coefficient_mul_asm","coefficient_sub_asm","inv_ntt_asm","fwd_ntt_asm","fwd_ntt_parallel_asm","rearrange_asm","a_gen_asm","r2_gen_asm","encode_message_asm","r1_gen_asm","key_gen_asm","RLWE_dec_asm","umod_asm","coefficient_sub_asm" 9 | 10 | def check(identifier): 11 | datafile = file('main.elf.dump') 12 | for line in datafile: 13 | if identifier in line: 14 | return line.split(" ",1)[0] 15 | 16 | for i in range(0, len(starts)): 17 | pos1 = check("<"+starts[i]+">:"); 18 | pos2 = check("<"+ends[i]+">:"); 19 | 20 | # print pos1 21 | # print pos2 22 | print starts[i] + ": " + str(int(pos2,16)-int(pos1,16)) 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This source code of the Ring-LWE Encryption Scheme is released under the 2 | MPL 1.1/GPL 2.0/LGPL 2.1 triple license. 3 | 4 | ------------------------------------------------------------------------------ 5 | Copyright (c) 2014, KU Leuven. All rights reserved. 6 | 7 | The initial developer of this source code is Ruan de Clercq, and 8 | Sujoy Sinha Roy, KU Leuven. Contact ruan.declercq@esat.kuleuven.be and 9 | Sujoy.SinhaRoy@esat.kuleuven.be for comments & questions. 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | 1. Redistributions of source code must retain the above copyright notice, 14 | this list of conditions and the following disclaimer. 15 | 16 | 2. Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in 18 | the documentation and/or other materials provided with the distribution. 19 | 20 | 3. The names of the authors may not be used to endorse or promote products 21 | derived from this source code without specific prior written permission. 22 | 23 | THIS SOURCE CODE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 24 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 25 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KU LEUVEN OR 26 | ANY CONTRIBUTORS TO THIS SOURCE CODE BE LIABLE FOR ANY DIRECT, INDIRECT, 27 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 | OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/lwe_arm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * test_asm.h 3 | * 4 | * Created on: Jul 1, 2014 5 | * Author: rdeclerc 6 | */ 7 | 8 | #ifndef LWE_ARM_H_ 9 | #define LWE_ARM_H_ 10 | 11 | #include "global.h" 12 | #include "stdint.h" 13 | 14 | #define attribute_fixed_data1 __attribute__((section(".fixed_data1"))); 15 | extern uint16_t fixed_data1[M] attribute_fixed_data1; 16 | extern uint16_t fixed_data2[M] attribute_fixed_data1; 17 | extern uint16_t fixed_data3[M] attribute_fixed_data1; 18 | 19 | void knuth_yao_shuffled_with_asm_optimization(uint16_t * out); 20 | int knuth_yao_asm(uint16_t * vals); 21 | int knuth_yao_asm_shuffle(uint16_t * vals); 22 | 23 | void asmtest(); 24 | 25 | int knuth_yao_single_number_asm(uint32_t * rnd); 26 | uint32_t umod_asm(uint32_t a); 27 | uint32_t mod_asm(uint32_t a); 28 | uint32_t smod_asm(uint32_t a); 29 | uint32_t umod_asm_simd(uint32_t a); 30 | 31 | void coefficient_add_asm(uint16_t * out, uint16_t * b, uint16_t * c); 32 | void coefficient_mul_asm(uint16_t * out, uint16_t * b, uint16_t * c); 33 | void coefficient_sub_asm(uint16_t * out, uint16_t * b, uint16_t * c); 34 | void coefficient_mul_add_asm(uint16_t * out, uint16_t * large1, uint16_t * large2, uint16_t * large3); 35 | 36 | void a_gen_asm(uint16_t * a); 37 | void r1_gen_asm(uint16_t * r1); 38 | void r2_gen_asm(uint16_t * r2); 39 | 40 | void rearrange_asm(uint16_t * a); 41 | 42 | void fwd_ntt_asm(uint16_t * a); 43 | void inv_ntt_asm(uint16_t * a); 44 | 45 | void encode_message_asm(uint16_t * destination, uint16_t * source); 46 | 47 | void fwd_ntt_parallel_asm(uint16_t * a); 48 | void RLWE_dec_asm(uint16_t * c1, uint16_t * c2, uint16_t * r2); 49 | void RLWE_enc_asm(uint16_t * a, uint16_t * c1, uint16_t * c2, uint16_t * out, uint16_t * p); 50 | void message_gen_asm(uint16_t * out); 51 | void key_gen_asm(uint16_t * a, uint16_t * r1, uint16_t * r2); 52 | void rearrange_for_final_test_asm(uint32_t in[M],uint32_t out[M]); 53 | 54 | void bitreverse_asm(uint32_t a[M]); 55 | void insert_highval(uint32_t * a, uint32_t b); 56 | void insert_lowval(uint32_t * a, uint32_t b); 57 | void ntt_multiply_asm(uint16_t * a, uint16_t * b, uint16_t * out); 58 | 59 | #endif /* LWE_ARM_H_ */ 60 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include // I recommend you have a look at these in the ST firmware folder 3 | #include // under Libraries/STM32F4xx_StdPeriph_Driver/inc and src 4 | #include 5 | #include 6 | #include 7 | #include "global.h" 8 | #include "lwe_arm.h" 9 | #include "speed_test.h" 10 | #include "term_io.h" 11 | #include "stdlib.h" 12 | #include "unit_test.h" 13 | 14 | void Delay(__IO uint32_t nCount) { 15 | while(nCount--) { 16 | } 17 | } 18 | 19 | uint32_t TM_RNG_Get(void) { 20 | //Wait until one RNG number is ready 21 | while(RNG_GetFlagStatus(RNG_FLAG_DRDY) == RESET); 22 | 23 | //Get a 32bit Random number 24 | //return RNG_GetRandomNumber(); 25 | return RNG->DR; 26 | } 27 | 28 | void initAll () 29 | { 30 | comm_init(); 31 | 32 | //RNG Peripheral enable 33 | RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE); 34 | RNG_Cmd(ENABLE); 35 | } 36 | 37 | void print_array(uint32_t a[]) 38 | { 39 | for (int i=0; i>= 1; 68 | } 69 | } 70 | 71 | #endif 72 | 73 | #ifdef GENERATE_BINARY_RANDOM_BITS 74 | uint32_t i=0; 75 | uint32_t n; 76 | for (i=0; i>8)&0xff),((n>>16)&0xff),((n>>24)&0xff)); 81 | } 82 | #endif 83 | 84 | #ifdef PERFORM_UNIT_TESTS 85 | perform_unit_tests(); 86 | #endif 87 | 88 | #ifdef PERFORM_SPEED_TESTS 89 | speed_test(); 90 | #endif 91 | 92 | xputs("[Done]\n\n"); 93 | 94 | while (1) 95 | { 96 | } 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/lwe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lwe.h 3 | * 4 | * Created on: Jul 3, 2014 5 | * Author: rdeclerc 6 | */ 7 | 8 | #include 9 | 10 | #ifndef __LWE_H_ 11 | #define __LWE_H_ 12 | 13 | #include "global.h" 14 | #include 15 | 16 | #ifdef USE_FAKE_GET_RAND 17 | extern uint32_t g_fake_rand; 18 | #endif 19 | 20 | bool compare_vectors(uint32_t *a, uint32_t *b); 21 | uint32_t knuth_yao_smaller_tables_single_number(uint32_t *rnd); 22 | uint32_t knuth_yao_single_number_optimized(uint32_t *rnd); 23 | uint32_t knuth_yao_single_number_pmat_optimized(); 24 | uint32_t knuth_yao_single_number(uint32_t *rnd, int * sample_in_table); 25 | void knuth_yao_smaller_tables2(uint32_t a[M]); 26 | void bitreverse2(uint16_t a[M]); 27 | void knuth_yao2(uint16_t a[M]); 28 | void knuth_yao_shuffled(uint16_t result[M]); 29 | 30 | uint16_t mod(uint32_t a); 31 | uint32_t compare_simd(uint32_t a_0[128], uint32_t a_1[128], uint32_t large[M]); 32 | uint32_t compare_large_simd(uint32_t large_simd[M / 2], uint32_t large[M]); 33 | void coefficient_add2(uint16_t out[M], uint16_t b[M], uint16_t c[M]); 34 | void a_gen2(uint16_t a[]); 35 | void r1_gen2(uint16_t r1[]); 36 | void r2_gen2(uint16_t r2[M]); 37 | void key_gen2(uint16_t a[M], uint16_t p[M], uint16_t r2[M]); 38 | void coefficient_mul_add2(uint16_t *result, uint16_t *large1, uint16_t *large2, uint16_t *large3); 39 | void coefficient_mul2(uint16_t out[M], uint16_t b[], uint16_t c[]); 40 | void coefficient_sub2(uint16_t result[M], uint16_t b[M], uint16_t c[M]); 41 | void message_gen2(uint16_t m[M]); 42 | void RLWE_enc2(uint16_t a[M], uint16_t c1[M], uint16_t c2[M], uint16_t m[M], uint16_t p[M]); 43 | void RLWE_dec2(uint16_t c1[M], uint16_t c2[M], uint16_t r2[M]); 44 | void fwd_ntt2(uint16_t a[]); 45 | void inv_ntt2(uint16_t a[M]); 46 | void rearrange2(uint16_t a[M]); 47 | void get_ntt_random_numbers(uint32_t *large1, uint32_t *large2, uint32_t i); 48 | void get_small_ntt_random_numbers(uint16_t *small1, uint16_t *small2, uint32_t i); 49 | void rearrange_for_final_test(uint16_t in[M], uint16_t out[M]); 50 | void get_rand_input(uint32_t i, uint32_t large1[M], uint32_t large2[M]); 51 | uint32_t get_rand(); 52 | uint32_t get_rand_basic(); 53 | 54 | #endif /* LWE_H_ */ 55 | -------------------------------------------------------------------------------- /x86/lwe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * lwe.h 3 | * 4 | * Created on: Jul 3, 2014 5 | * Author: rdeclerc 6 | */ 7 | 8 | #include 9 | 10 | #ifndef __LWE_H_ 11 | #define __LWE_H_ 12 | 13 | #include "global.h" 14 | #include 15 | 16 | #ifdef USE_FAKE_GET_RAND 17 | extern uint32_t g_fake_rand; 18 | #endif 19 | 20 | bool compare_vectors(uint16_t *a, uint16_t *b); 21 | uint32_t knuth_yao_smaller_tables_single_number(uint32_t *rnd); 22 | uint32_t knuth_yao_single_number_optimized(uint32_t *rnd); 23 | uint32_t knuth_yao_single_number_pmat_optimized(); 24 | uint32_t knuth_yao_single_number(uint32_t *rnd, int * sample_in_table); 25 | void knuth_yao_small(uint16_t a[M]); 26 | void knuth_yao_smaller_tables2(uint16_t a[M]); 27 | void bitreverse2(uint16_t a[M]); 28 | void knuth_yao2(uint16_t a[M]); 29 | void knuth_yao_shuffled(uint16_t result[M]); 30 | 31 | uint16_t mod(uint32_t a); 32 | uint32_t compare_simd(uint32_t a_0[128], uint32_t a_1[128], uint32_t large[M]); 33 | uint32_t compare_large_simd(uint32_t large_simd[M / 2], uint32_t large[M]); 34 | void coefficient_add2(uint16_t out[M], uint16_t b[M], uint16_t c[M]); 35 | void a_gen2(uint16_t a[]); 36 | void r1_gen2(uint16_t r1[]); 37 | void r2_gen2(uint16_t r2[M]); 38 | void key_gen2(uint16_t a[M], uint16_t p[M], uint16_t r2[M]); 39 | void coefficient_mul_add2(uint16_t *result, uint16_t *large1, uint16_t *large2, uint16_t *large3); 40 | void coefficient_mul2(uint16_t out[M], uint16_t b[], uint16_t c[]); 41 | void coefficient_sub2(uint16_t result[M], uint16_t b[M], uint16_t c[M]); 42 | void message_gen2(uint16_t m[M]); 43 | void RLWE_enc2(uint16_t a[M], uint16_t c1[M], uint16_t c2[M], uint16_t m[M], uint16_t p[M]); 44 | void RLWE_dec2(uint16_t c1[M], uint16_t c2[M], uint16_t r2[M]); 45 | void fwd_ntt2(uint16_t a[]); 46 | void inv_ntt2(uint16_t a[M]); 47 | void rearrange2(uint16_t a[M]); 48 | void get_ntt_random_numbers(uint32_t *large1, uint32_t *large2, uint32_t i); 49 | void get_small_ntt_random_numbers(uint16_t *small1, uint16_t *small2, uint32_t i); 50 | void rearrange_for_final_test(uint16_t in[M], uint16_t out[M]); 51 | void get_rand_input(uint32_t i, uint32_t large1[M], uint32_t large2[M]); 52 | uint32_t get_rand(); 53 | uint32_t get_rand_basic(); 54 | 55 | #endif /* LWE_H_ */ 56 | -------------------------------------------------------------------------------- /x86/global.h: -------------------------------------------------------------------------------- 1 | #ifndef __GLOBAL_H_ 2 | #define __GLOBAL_H_ 3 | 4 | //#define DEBUG_PRINTF 5 | 6 | //#define USE_FAKE_GET_RAND 7 | 8 | //#define GENERATE_BINARY_RANDOM_BITS 9 | //#define GENERATE_ASCII_RANDOM_BITS 10 | #define NUMBER_OF_RANDOM_BITS 10000000 11 | #define NUMBER_OF_RANDOM_WORDS NUMBER_OF_RANDOM_BITS/4 12 | 13 | #define GENERATE_RANDOM_BITS 14 | 15 | 16 | //#define DISABLE_KNUTH_YAO 17 | #define INNER_REPEAT_COUNT 1 18 | 19 | 20 | #define USE_PARALLEL 21 | 22 | //#define PERFORM_DECRYPTION_ERROR_TEST 23 | 24 | #define PERFORM_UNIT_TESTS 25 | #define PERFORM_UNIT_TESTS_BIG 26 | //#define PERFORM_UNIT_TESTS_SMALL 27 | 28 | 29 | #define PERFORM_SPEED_TESTS 30 | #define PERFORM_BIG_SPEED_TESTS 31 | #define PERFORM_SMALL_SPEED_TESTS 32 | 33 | 34 | #define UNIT_TEST_BIG_LOOPS 100 35 | #define UNIT_TEST_SMALL_LOOPS 500 36 | #define SPEED_TEST_BIG_LOOPS 10000 37 | #define SPEED_TEST_SMALL_LOOPS 1000 38 | 39 | 40 | //#define NTT512 41 | //#define KNUTH_YAO_512 42 | 43 | #ifdef KNUTH_YAO_512 44 | #define LOW_MSB 26 45 | #define HAMMING_TABLE_SIZE 10 46 | #define PMAT_MAX_COL 106 47 | #define KN_DISTANCE1_MASK 15 48 | #define KN_DISTANCE2_MASK 15 49 | #else 50 | #define LOW_MSB 22 51 | #define HAMMING_TABLE_SIZE 8 52 | #define PMAT_MAX_COL 109 53 | #define KN_DISTANCE1_MASK 7 54 | #define KN_DISTANCE2_MASK 15 55 | #endif 56 | 57 | #ifdef NTT512 58 | #define MODULUS 12289 59 | #define M 512 60 | #define UMOD_CONSTANT 0xAAA71C85 61 | #define QBY2 6144 62 | #define QBY4 3072 63 | #define QBY4_TIMES3 9216 64 | 65 | #define FWD_CONST1 5559 66 | #define FWD_CONST2 6843 67 | 68 | #define INVCONST1 3778 69 | #define INVCONST2 10810 70 | #define INVCONST3 9087 71 | #define SCALING 12265 72 | 73 | #define COEFFICIENT_ALL_ONES 0x3FFF//14 bits 74 | 75 | #else 76 | #define MODULUS 7681 77 | #define M 256 78 | #define UMOD_CONSTANT 0x4441fdcd 79 | #define QBY2 3840 80 | #define QBY4 1920 81 | #define QBY4_TIMES3 5760 82 | 83 | #define FWD_CONST1 5118 84 | #define FWD_CONST2 1065 85 | 86 | #define INVCONST1 2880 87 | #define INVCONST2 3383 88 | #define INVCONST3 2481 89 | #define SCALING 7651 90 | #define COEFFICIENT_ALL_ONES 0x1FFF//13 bits 91 | #endif 92 | 93 | 94 | //#define USE_TRNG 95 | #define RNG_ADDR 0x50060800 96 | 97 | 98 | #endif 99 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/stm32f4xx_it.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file GPIO/GPIO_IOToggle/stm32f4xx_it.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 18-January-2013 7 | * @brief This file contains the headers of the interrupt handlers. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F4xx_IT_H 30 | #define __STM32F4xx_IT_H 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /* Includes ------------------------------------------------------------------*/ 37 | #include "stm32f4xx.h" 38 | 39 | /* Exported types ------------------------------------------------------------*/ 40 | /* Exported constants --------------------------------------------------------*/ 41 | /* Exported macro ------------------------------------------------------------*/ 42 | /* Exported functions ------------------------------------------------------- */ 43 | 44 | void NMI_Handler(void); 45 | void HardFault_Handler(void); 46 | void MemManage_Handler(void); 47 | void BusFault_Handler(void); 48 | void UsageFault_Handler(void); 49 | void SVC_Handler(void); 50 | void DebugMon_Handler(void); 51 | void PendSV_Handler(void); 52 | void SysTick_Handler(void); 53 | 54 | #ifdef __cplusplus 55 | } 56 | #endif 57 | 58 | #endif /* __STM32F4xx_IT_H */ 59 | 60 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Library for Public-Key Cryptography with Ring-LWE Encryption 2 | ======== 3 | This project contains a library to perform public-key cryptography that is post-quantum secure. Public-key crypto uses two keys, one public and one private, that are mathematically linked. The public key can be used to encrypt a plaintext message, after which the encrypted message can be decrypted by the private key. 4 | 5 | The underlying security of the scheme is based on the Ring-LWE problem. The library is capable of providing either 128-bit security or 256-bit security. Recent advances in post-quantum cryptography has highlighted the efficiency of using these schemes. This project aims to provide a working example of the underlying principles of Ring-LWE cryptography, and also to demonstrate how to make efficient implementations for this scheme. 6 | 7 | Post-Quantum Cryptography 8 | ========= 9 | Present day public-key schemes rely on the difficulty of performing factoring or the discrete logarithm for providing security, authenticity and privacy. For sufficiently large key sizes, these public-key cyptosystems are practically unsolvable using present day computers, super computers, or special hardware clusters. Peter Shor has proposed an algorithm for integer factorization, and this algorithm has been modified to be able to solve the elliptic curve discrete logarithm problem (ECDLP). Shor’s algorithms only runs on powerful quantum computers to solve the factoring or the discrete logarithm problems in polynomial time. 10 | 11 | Present day quantum computers are not yet capable of running Shor's algorithm, but we nevertheless need to think about the future. It is well-known that large government organizations (e.g., the United States' NSA and British Intelligence Agency MI5) are collecting vast amounts of communications data. This data is stored in large storage facilities where it might one day be analyzed, and all the public-key algorithms which was used, will become broken, allowing large amounts of sensitive information to be decrypted and analyzed. 12 | 13 | Supported Parameters Sets 14 | ========== 15 | This project supports two security parameter sets: 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
SecurityNumber of coefficients (n)Modulus (q)Sigma
128256768111.31/sqrrt(2*pi)
2565121228912.18/sqrrt(2*pi)
37 | 38 | How to use this library 39 | ========== 40 | Two different libraries are provided in this project. The first is a basic version for the x86 architecture. 41 | 42 | Further Reading 43 | ========== 44 | For a simple explanation of this work see "Efficient Software Implementation of Ring-LWE", available at https://eprint.iacr.org/2014/725.pdf. 45 | 46 | For a more detailed mathematical explanation of the Ring-LWE encryption scheme see "Compact Ring-LWE Cryptoprocessor", available at http://www.cosic.esat.kuleuven.be/publications/article-2444.pdf. 47 | 48 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/global.h: -------------------------------------------------------------------------------- 1 | #ifndef __GLOBAL_H_ 2 | #define __GLOBAL_H_ 3 | 4 | //#define USE_FAKE_GET_RAND 5 | 6 | //#define GENERATE_BINARY_RANDOM_BITS 7 | //#define GENERATE_ASCII_RANDOM_BITS 8 | #define NUMBER_OF_RANDOM_BITS 10000000 9 | #define NUMBER_OF_RANDOM_WORDS NUMBER_OF_RANDOM_BITS/4 10 | 11 | #define GENERATE_RANDOM_BITS 12 | 13 | 14 | //#define DISABLE_KNUTH_YAO 15 | #define INNER_REPEAT_COUNT 1 16 | 17 | #define USE_PARALLEL 18 | 19 | /*This is a big tests that counts the number of decryption errors that is 20 | *inherent with the unpadded Ring-LWE encryption scheme */ 21 | //#define PERFORM_DECRYPTION_ERROR_TEST 22 | 23 | //#define PERFORM_UNIT_TESTS 24 | #define PERFORM_UNIT_TESTS_BIG 25 | #define PERFORM_UNIT_TESTS_SMALL 26 | 27 | #define PERFORM_SPEED_TESTS 28 | #define PERFORM_BIG_SPEED_TESTS 29 | #define PERFORM_SMALL_SPEED_TESTS 30 | 31 | #define UNIT_TEST_BIG_LOOPS 10 32 | #define UNIT_TEST_SMALL_LOOPS 10 33 | #define SPEED_TEST_BIG_LOOPS 100000 34 | #define SPEED_TEST_SMALL_LOOPS 10000 35 | 36 | //#define USE_SMALL_TABLES 37 | 38 | //Provides protection against simple power analysis 39 | #define USE_KNUTH_YAO_SHUFFLE 40 | 41 | #define NTT512 42 | #define KNUTH_YAO_512 43 | 44 | #ifdef KNUTH_YAO_512 45 | #ifdef USE_SMALL_TABLES 46 | #define LOW_MSB 31 47 | #define HAMMING_TABLE_SIZE 21 48 | #else 49 | #define LOW_MSB 26 50 | #define HAMMING_TABLE_SIZE 10 //??? Should this not be 11?? 51 | #endif 52 | 53 | #define PMAT_MAX_COL 106 54 | #define PMAT_MAX_ROW 58 55 | #define KN_DISTANCE1_MASK 15 56 | #define KN_DISTANCE2_MASK 15 57 | #else 58 | #ifdef USE_SMALL_TABLES 59 | #define LOW_MSB 31 //Should be named "PMAT_LOW_OCCUPIED_BITS" 60 | #define HAMMING_TABLE_SIZE 25 //Should be named "PMAT_HIGH_COL_START" 61 | #else 62 | #define LOW_MSB 22 63 | #define HAMMING_TABLE_SIZE 8 64 | #endif 65 | 66 | #define PMAT_MAX_COL 109 67 | #define PMAT_MAX_ROW 54 68 | #define KN_DISTANCE1_MASK 7 69 | #define KN_DISTANCE2_MASK 15 70 | #endif 71 | #define LOW_MSB_PLUS_ONE LOW_MSB+1 72 | #define PMAT_MAX_ROW_ONE PMAT_MAX_ROW+1 73 | 74 | #ifdef NTT512 75 | #define MODULUS 12289 76 | #define M 512 77 | #define UMOD_CONSTANT 0xAAA71C85 78 | #define QBY2 6144 79 | #define QBY4 3072 80 | #define QBY4_TIMES3 9216 81 | 82 | #define FWD_CONST1 5559 83 | #define FWD_CONST2 6843 84 | 85 | #define INVCONST1 3778 86 | #define INVCONST2 10810 87 | #define INVCONST3 9087 88 | #define SCALING 12265 89 | 90 | #define COEFFICIENT_ALL_ONES 0x3FFF//14 bits 91 | 92 | #else 93 | #define MODULUS 7681 94 | #define M 256 95 | #define UMOD_CONSTANT 0x4441fdcd 96 | #define QBY2 3840 97 | #define QBY4 1920 98 | #define QBY4_TIMES3 5760 99 | 100 | #define FWD_CONST1 5118 101 | #define FWD_CONST2 1065 102 | 103 | #define INVCONST1 2880 104 | #define INVCONST2 3383 105 | #define INVCONST3 2481 106 | #define SCALING 7651 107 | #define COEFFICIENT_ALL_ONES 0x1FFF//13 bits 108 | #endif 109 | 110 | 111 | #define USE_TRNG 112 | #define RNG_ADDR 0x50060800 113 | 114 | /* 115 | #define NEW_RND_BOTTOM 0 116 | #define NEW_RND_LARGE 32-8 117 | #define NEW_RND_MID 32-5 118 | */ 119 | 120 | #define NEW_RND_BOTTOM 1 121 | #define NEW_RND_LARGE 32-9 122 | #define NEW_RND_MID 32-6 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/stm32f4xx_conf.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file GPIO/GPIO_IOToggle/stm32f4xx_conf.h 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 18-January-2013 7 | * @brief Library configuration file. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | *

© COPYRIGHT 2013 STMicroelectronics

12 | * 13 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 14 | * You may not use this file except in compliance with the License. 15 | * You may obtain a copy of the License at: 16 | * 17 | * http://www.st.com/software_license_agreement_liberty_v2 18 | * 19 | * Unless required by applicable law or agreed to in writing, software 20 | * distributed under the License is distributed on an "AS IS" BASIS, 21 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 | * See the License for the specific language governing permissions and 23 | * limitations under the License. 24 | * 25 | ****************************************************************************** 26 | */ 27 | 28 | /* Define to prevent recursive inclusion -------------------------------------*/ 29 | #ifndef __STM32F4xx_CONF_H 30 | #define __STM32F4xx_CONF_H 31 | 32 | /* Includes ------------------------------------------------------------------*/ 33 | /* Uncomment the line below to enable peripheral header file inclusion */ 34 | #include "stm32f4xx_adc.h" 35 | #include "stm32f4xx_can.h" 36 | #include "stm32f4xx_crc.h" 37 | #include "stm32f4xx_cryp.h" 38 | #include "stm32f4xx_dac.h" 39 | #include "stm32f4xx_dbgmcu.h" 40 | #include "stm32f4xx_dcmi.h" 41 | #include "stm32f4xx_dma.h" 42 | #include "stm32f4xx_exti.h" 43 | #include "stm32f4xx_flash.h" 44 | #include "stm32f4xx_fsmc.h" 45 | #include "stm32f4xx_hash.h" 46 | #include "stm32f4xx_gpio.h" 47 | #include "stm32f4xx_i2c.h" 48 | #include "stm32f4xx_iwdg.h" 49 | #include "stm32f4xx_pwr.h" 50 | #include "stm32f4xx_rcc.h" 51 | #include "stm32f4xx_rng.h" 52 | #include "stm32f4xx_rtc.h" 53 | #include "stm32f4xx_sdio.h" 54 | #include "stm32f4xx_spi.h" 55 | #include "stm32f4xx_syscfg.h" 56 | #include "stm32f4xx_tim.h" 57 | #include "stm32f4xx_usart.h" 58 | #include "stm32f4xx_wwdg.h" 59 | #include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */ 60 | 61 | /* Exported types ------------------------------------------------------------*/ 62 | /* Exported constants --------------------------------------------------------*/ 63 | 64 | /* If an external clock source is used, then the value of the following define 65 | should be set to the value of the external clock source, else, if no external 66 | clock is used, keep this define commented */ 67 | /*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */ 68 | 69 | 70 | /* Uncomment the line below to expanse the "assert_param" macro in the 71 | Standard Peripheral Library drivers code */ 72 | /* #define USE_FULL_ASSERT 1 */ 73 | 74 | /* Exported macro ------------------------------------------------------------*/ 75 | #ifdef USE_FULL_ASSERT 76 | 77 | /** 78 | * @brief The assert_param macro is used for function's parameters check. 79 | * @param expr: If expr is false, it calls assert_failed function 80 | * which reports the name of the source file and the source 81 | * line number of the call that failed. 82 | * If expr is true, it returns no value. 83 | * @retval None 84 | */ 85 | #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) 86 | /* Exported functions ------------------------------------------------------- */ 87 | void assert_failed(uint8_t* file, uint32_t line); 88 | #else 89 | #define assert_param(expr) ((void)0) 90 | #endif /* USE_FULL_ASSERT */ 91 | 92 | #endif /* __STM32F4xx_CONF_H */ 93 | 94 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 95 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/Makefile: -------------------------------------------------------------------------------- 1 | TARGET=main.hex 2 | EXECUTABLE=main.elf 3 | BINTARGET=main.bin 4 | TOOLCHAIN_PATH=~/localdisk/toolchains/gcc-arm-none-eabi-4_8-2014q2/bin 5 | STFLASH=/users/cosic/rdeclerc/localdisk/toolchains/stlink/install/bin/st-flash 6 | STUTIL=/users/cosic/rdeclerc/localdisk/toolchains/stlink/install/bin/st-util 7 | 8 | 9 | CC=${TOOLCHAIN_PATH}/arm-none-eabi-gcc 10 | LD=${TOOLCHAIN_PATH}/arm-none-eabi-gcc 11 | AR=${TOOLCHAIN_PATH}/arm-none-eabi-ar 12 | AS=${TOOLCHAIN_PATH}/arm-none-eabi-as 13 | CP=${TOOLCHAIN_PATH}/arm-none-eabi-objcopy 14 | OD=${TOOLCHAIN_PATH}/arm-none-eabi-objdump 15 | 16 | BIN=$(CP) -O ihex 17 | 18 | STD_PERIPH=/users/cosic/rdeclerc/templates/STM32F4-workarea/Libraries/STM32F4xx_StdPeriph_Driver 19 | #STD_PERIPH=/home/rdeclerc/templates/STM32F4-workarea/Libraries/STM32F4xx_StdPeriph_Driver-g 20 | CMSIS=/users/cosic/rdeclerc/templates/STM32F4-workarea/Libraries/CMSIS 21 | #CMSIS=/home/rdeclerc/templates/STM32F4-workarea/Libraries/CMSIS 22 | 23 | DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F4XX -DHSE_VALUE=8000000 24 | STARTUP = ./startup_stm32f40xx.s 25 | 26 | MCU = cortex-m4 27 | MCFLAGS = -mcpu=$(MCU) -mthumb -mlittle-endian -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb-interwork -std=c99 -g3 -Wunused 28 | STM32_INCLUDES = -I$(CMSIS)/Device/ST/STM32F4xx/Include/ \ 29 | -I$(CMSIS)/Include/ \ 30 | -I$(STD_PERIPH)/inc 31 | 32 | OPTIMIZE = -O0 33 | 34 | CFLAGS = $(MCFLAGS) $(OPTIMIZE) $(DEFS) -I. -I./ $(STM32_INCLUDES) -Wl,-T,stm32_flash.ld 35 | AFLAGS = $(MCFLAGS) 36 | #-mapcs-float use float regs. small increase in code size 37 | 38 | SRC = main.c \ 39 | stm32f4xx_it.c \ 40 | system_stm32f4xx.c \ 41 | lwe.c \ 42 | knuth_yao_asm.S \ 43 | knuth_yao_asm_shuffle.S \ 44 | lwe_arm.S \ 45 | lwe_arm.c \ 46 | term_io.c \ 47 | comm.c \ 48 | speed_test.c \ 49 | global.c \ 50 | unit_test.c \ 51 | $(STD_PERIPH)/src/misc.c \ 52 | $(STD_PERIPH)/src/stm32f4xx_adc.c \ 53 | $(STD_PERIPH)/src/stm32f4xx_can.c \ 54 | $(STD_PERIPH)/src/stm32f4xx_crc.c \ 55 | $(STD_PERIPH)/src/stm32f4xx_cryp_aes.c \ 56 | $(STD_PERIPH)/src/stm32f4xx_cryp.c \ 57 | $(STD_PERIPH)/src/stm32f4xx_cryp_des.c \ 58 | $(STD_PERIPH)/src/stm32f4xx_cryp_tdes.c \ 59 | $(STD_PERIPH)/src/stm32f4xx_dac.c \ 60 | $(STD_PERIPH)/src/stm32f4xx_dbgmcu.c \ 61 | $(STD_PERIPH)/src/stm32f4xx_dcmi.c \ 62 | $(STD_PERIPH)/src/stm32f4xx_dma.c \ 63 | $(STD_PERIPH)/src/stm32f4xx_exti.c \ 64 | $(STD_PERIPH)/src/stm32f4xx_flash.c \ 65 | $(STD_PERIPH)/src/stm32f4xx_fsmc.c \ 66 | $(STD_PERIPH)/src/stm32f4xx_gpio.c \ 67 | $(STD_PERIPH)/src/stm32f4xx_hash.c \ 68 | $(STD_PERIPH)/src/stm32f4xx_hash_md5.c \ 69 | $(STD_PERIPH)/src/stm32f4xx_hash_sha1.c \ 70 | $(STD_PERIPH)/src/stm32f4xx_i2c.c \ 71 | $(STD_PERIPH)/src/stm32f4xx_iwdg.c \ 72 | $(STD_PERIPH)/src/stm32f4xx_pwr.c \ 73 | $(STD_PERIPH)/src/stm32f4xx_rcc.c \ 74 | $(STD_PERIPH)/src/stm32f4xx_rng.c \ 75 | $(STD_PERIPH)/src/stm32f4xx_rtc.c \ 76 | $(STD_PERIPH)/src/stm32f4xx_sdio.c \ 77 | $(STD_PERIPH)/src/stm32f4xx_spi.c \ 78 | $(STD_PERIPH)/src/stm32f4xx_syscfg.c \ 79 | $(STD_PERIPH)/src/stm32f4xx_tim.c \ 80 | $(STD_PERIPH)/src/stm32f4xx_usart.c \ 81 | $(STD_PERIPH)/src/stm32f4xx_wwdg.c 82 | 83 | OBJDIR = . 84 | OBJ = $(SRC:%.c=$(OBJDIR)/%.o) 85 | OBJ = $(OBJ:%.s=$(OBJDIR)/%.o) 86 | OBJ = $(OBJ:%.S=$(OBJDIR)/%.o) 87 | OBJ += Startup.o 88 | 89 | all: $(TARGET) 90 | 91 | $(BINTARGET):all 92 | $(CP) -O binary $(EXECUTABLE) $(BINTARGET) 93 | 94 | $(TARGET): $(EXECUTABLE) 95 | $(CP) -O ihex $^ $@ 96 | 97 | $(EXECUTABLE): $(SRC) $(STARTUP) 98 | $(CC) $(CFLAGS) $^ -lm -lc -lnosys -o $@ 99 | 100 | clean: 101 | # rm -f Startup.lst $(TARGET) $(TARGET).lst $(OBJ) $(AUTOGEN) $(TARGET).out $(TARGET).hex $(TARGET).map $(TARGET).dmp $(TARGET).elf 102 | rm -f main.elf main.hex main.elf.dump main.bin 103 | 104 | program: $(BINTARGET) 105 | ${STFLASH} --reset write $(BINTARGET) 0x8000000 106 | 107 | disassemble: $(TARGET) 108 | arm-none-eabi-objdump $(EXECUTABLE) --disassemble > $(EXECUTABLE).dump 109 | 110 | uart: 111 | make clean 112 | make program 113 | screen /dev/ttyUSB0 9600 114 | 115 | acm0: 116 | screen /dev/ttyACM0 9600 117 | 118 | gdb-server: 119 | ${STUTIL} 120 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /x86/main.c: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | //#include "luts.h" 3 | #include "lwe.h" 4 | #include "stdio.h" 5 | #include "lwe_original.h" 6 | 7 | 8 | void main() 9 | { 10 | int i; 11 | int j; 12 | int res; 13 | uint16_t large_m[M],large_a[M],large_p[M],large_r2[M],large_c1[M],large_c2[M],large1[M],large2[M]; 14 | uint32_t a_0[M/2],a_1[M/2]; 15 | 16 | 17 | printf("knuth_yao_smaller_tables2: "); 18 | res = 1; 19 | for (i=0; i<0x4FF; i++) 20 | { 21 | if ((i%100)==0) 22 | printf("."); 23 | srand(i*i); 24 | #ifdef USE_KNUTH_YAO_ORIGINAL 25 | knuth_yao_original(a_0,a_1); 26 | #else 27 | knuth_yao(a_0,a_1); 28 | #endif 29 | 30 | srand(i*i); 31 | knuth_yao_smaller_tables2(large1); 32 | 33 | if (compare2(a_1,a_0,large1)==0) 34 | { 35 | res=0; 36 | printf("i=%d\n",i); 37 | break; 38 | } 39 | } 40 | if (res==0) 41 | printf("BAD!\n"); 42 | else 43 | printf("OK!\n"); 44 | 45 | 46 | 47 | #ifdef USE_FAKE_GET_RAND 48 | printf("knuth_yao_asm_fake_get_rand:"); 49 | i=0xFFFFF0FF; 50 | //for (i=0xFFFFF0FF; i<0xffffffff; i++) 51 | { 52 | g_fake_rand=i; 53 | 54 | srand(i); 55 | knuth_yao2(large2); 56 | 57 | printf("i=%d num=%x\n",i,large1[0]>>16); 58 | return; 59 | } 60 | #endif 61 | 62 | res = 1; 63 | for (i=0; i<32767; i++) 64 | { 65 | srand(i*i); 66 | #ifdef USE_KNUTH_YAO_ORIGINAL 67 | knuth_yao_original(a_0,a_1); 68 | #else 69 | knuth_yao(a_0,a_1); 70 | #endif 71 | 72 | srand(i*i); 73 | knuth_yao2(large1); 74 | 75 | if (compare2(a_0,a_1,large1)==0) 76 | { 77 | res=0; 78 | break; 79 | } 80 | } 81 | printf("knuth_yao2: "); 82 | if (res==0) 83 | printf("BAD!\n"); 84 | else 85 | printf("OK!\n"); 86 | int sample_in_table; 87 | 88 | for (i=0; i<327670; i++) 89 | { 90 | srand(i*i); 91 | uint32_t rnd = get_rand(); 92 | uint32_t num1 = knuth_yao_single_number(&rnd,&sample_in_table); 93 | 94 | srand(i*i); 95 | rnd = get_rand(); 96 | uint32_t num2 = knuth_yao_smaller_tables_single_number(&rnd); 97 | 98 | if (num1!=num2) 99 | { 100 | res=0; 101 | printf("i=%d\n",i); 102 | break; 103 | } 104 | } 105 | printf("knuth_yao_smaller_tables_single_number: "); 106 | if (res==0) 107 | printf("BAD!\n"); 108 | else 109 | printf("OK!\n"); 110 | 111 | res=1; 112 | res = 1; 113 | for (i=0; (i<1000) && (res==1); i++) 114 | { 115 | srand(i); 116 | if (i==0) 117 | { 118 | //All ones for first test case 119 | for (j=0; jQBY4) && (large_c1[j]
© COPYRIGHT 2013 STMicroelectronics
14 | * 15 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 16 | * You may not use this file except in compliance with the License. 17 | * You may obtain a copy of the License at: 18 | * 19 | * http://www.st.com/software_license_agreement_liberty_v2 20 | * 21 | * Unless required by applicable law or agreed to in writing, software 22 | * distributed under the License is distributed on an "AS IS" BASIS, 23 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24 | * See the License for the specific language governing permissions and 25 | * limitations under the License. 26 | * 27 | ****************************************************************************** 28 | */ 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | #include "stm32f4xx_it.h" 32 | 33 | /** @addtogroup Template_Project 34 | * @{ 35 | */ 36 | 37 | /* Private typedef -----------------------------------------------------------*/ 38 | /* Private define ------------------------------------------------------------*/ 39 | /* Private macro -------------------------------------------------------------*/ 40 | /* Private variables ---------------------------------------------------------*/ 41 | /* Private function prototypes -----------------------------------------------*/ 42 | /* Private functions ---------------------------------------------------------*/ 43 | 44 | /******************************************************************************/ 45 | /* Cortex-M4 Processor Exceptions Handlers */ 46 | /******************************************************************************/ 47 | 48 | /** 49 | * @brief This function handles NMI exception. 50 | * @param None 51 | * @retval None 52 | */ 53 | void NMI_Handler(void) 54 | { 55 | } 56 | 57 | /** 58 | * @brief This function handles Hard Fault exception. 59 | * @param None 60 | * @retval None 61 | */ 62 | void HardFault_Handler(void) 63 | { 64 | /* Go to infinite loop when Hard Fault exception occurs */ 65 | while (1) 66 | { 67 | } 68 | } 69 | 70 | /** 71 | * @brief This function handles Memory Manage exception. 72 | * @param None 73 | * @retval None 74 | */ 75 | void MemManage_Handler(void) 76 | { 77 | /* Go to infinite loop when Memory Manage exception occurs */ 78 | while (1) 79 | { 80 | } 81 | } 82 | 83 | /** 84 | * @brief This function handles Bus Fault exception. 85 | * @param None 86 | * @retval None 87 | */ 88 | void BusFault_Handler(void) 89 | { 90 | /* Go to infinite loop when Bus Fault exception occurs */ 91 | while (1) 92 | { 93 | } 94 | } 95 | 96 | /** 97 | * @brief This function handles Usage Fault exception. 98 | * @param None 99 | * @retval None 100 | */ 101 | void UsageFault_Handler(void) 102 | { 103 | /* Go to infinite loop when Usage Fault exception occurs */ 104 | while (1) 105 | { 106 | } 107 | } 108 | 109 | /** 110 | * @brief This function handles SVCall exception. 111 | * @param None 112 | * @retval None 113 | */ 114 | void SVC_Handler(void) 115 | { 116 | } 117 | 118 | /** 119 | * @brief This function handles Debug Monitor exception. 120 | * @param None 121 | * @retval None 122 | */ 123 | void DebugMon_Handler(void) 124 | { 125 | } 126 | 127 | /** 128 | * @brief This function handles PendSVC exception. 129 | * @param None 130 | * @retval None 131 | */ 132 | void PendSV_Handler(void) 133 | { 134 | } 135 | 136 | /** 137 | * @brief This function handles SysTick Handler. 138 | * @param None 139 | * @retval None 140 | */ 141 | void SysTick_Handler(void) 142 | { 143 | } 144 | 145 | /******************************************************************************/ 146 | /* STM32F4xx Peripherals Interrupt Handlers */ 147 | /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ 148 | /* available peripheral interrupt handler's name please refer to the startup */ 149 | /* file (startup_stm32f40xx.s/startup_stm32f427x.s). */ 150 | /******************************************************************************/ 151 | 152 | /** 153 | * @brief This function handles PPP interrupt request. 154 | * @param None 155 | * @retval None 156 | */ 157 | /*void PPP_IRQHandler(void) 158 | { 159 | }*/ 160 | 161 | /** 162 | * @} 163 | */ 164 | 165 | 166 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 167 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/term_io.c: -------------------------------------------------------------------------------- 1 | // Basic code from ChaN, minor modifications by Martin Thomas 2 | 3 | #include 4 | #include "term_io.h" 5 | 6 | int xatoi (char **str, long *res) 7 | { 8 | uint32_t val; 9 | uint8_t c, radix, s = 0; 10 | 11 | while ((c = **str) == ' ') 12 | (*str)++; 13 | if (c == '-') 14 | { 15 | s = 1; 16 | c = *(++(*str)); 17 | } 18 | if (c == '0') 19 | { 20 | c = *(++(*str)); 21 | if (c <= ' ') 22 | { 23 | *res = 0; 24 | return 1; 25 | } 26 | if (c == 'x') 27 | { 28 | radix = 16; 29 | c = *(++(*str)); 30 | } 31 | else 32 | { 33 | if (c == 'b') 34 | { 35 | radix = 2; 36 | c = *(++(*str)); 37 | } 38 | else 39 | { 40 | if ((c >= '0') && (c <= '9')) 41 | radix = 8; 42 | else 43 | return 0; 44 | } 45 | } 46 | } 47 | else 48 | { 49 | if ((c < '1') || (c > '9')) 50 | return 0; 51 | radix = 10; 52 | } 53 | val = 0; 54 | while (c > ' ') 55 | { 56 | if (c >= 'a') 57 | c -= 0x20; 58 | c -= '0'; 59 | if (c >= 17) 60 | { 61 | c -= 7; 62 | if (c <= 9) 63 | return 0; 64 | } 65 | if (c >= radix) 66 | return 0; 67 | val = val * radix + c; 68 | c = *(++(*str)); 69 | } 70 | if (s) 71 | val = -val; 72 | *res = val; 73 | return 1; 74 | } 75 | 76 | void xputc (char c) 77 | { 78 | if (c == '\n') 79 | comm_put('\r'); 80 | comm_put(c); 81 | } 82 | 83 | void xputs (const char* str) 84 | { 85 | while (*str) 86 | xputc(*str++); 87 | } 88 | 89 | void xitoa (long val, int radix, int len) 90 | { 91 | uint8_t c, r, sgn = 0, pad = ' '; 92 | uint8_t s[20], i = 0; 93 | uint32_t v; 94 | 95 | if (radix < 0) 96 | { 97 | radix = -radix; 98 | if (val < 0) 99 | { 100 | val = -val; 101 | sgn = '-'; 102 | } 103 | } 104 | v = val; 105 | r = radix; 106 | if (len < 0) 107 | { 108 | len = -len; 109 | pad = '0'; 110 | } 111 | if (len > 20) 112 | return; 113 | do 114 | { 115 | c = (uint8_t) (v % r); 116 | if (c >= 10) 117 | c += 7; 118 | c += '0'; 119 | s[i++] = c; 120 | v /= r; 121 | } while (v); 122 | if (sgn) 123 | s[i++] = sgn; 124 | while (i < len) 125 | s[i++] = pad; 126 | do 127 | xputc(s[--i]); 128 | while (i); 129 | } 130 | 131 | void xprintf (const char* str, ...) 132 | { 133 | va_list arp; 134 | int d, r, w, s, l; 135 | 136 | va_start(arp, str); 137 | 138 | while ((d = *str++) != 0) 139 | { 140 | if (d != '%') 141 | { 142 | xputc(d); 143 | continue; 144 | } 145 | d = *str++; 146 | w = r = s = l = 0; 147 | if (d == '0') 148 | { 149 | d = *str++; 150 | s = 1; 151 | } 152 | while ((d >= '0') && (d <= '9')) 153 | { 154 | w += w * 10 + (d - '0'); 155 | d = *str++; 156 | } 157 | if (s) 158 | w = -w; 159 | if (d == 'l') 160 | { 161 | l = 1; 162 | d = *str++; 163 | } 164 | if (!d) 165 | break; 166 | if (d == 's') 167 | { 168 | xputs(va_arg(arp, char*)); 169 | continue; 170 | } 171 | if (d == 'c') 172 | { 173 | xputc((char) va_arg(arp, int)); 174 | continue; 175 | } 176 | if (d == 'u') 177 | r = 10; 178 | if (d == 'd') 179 | r = -10; 180 | if (d == 'X' || d == 'x') 181 | r = 16; // 'x' added by mthomas in increase compatibility 182 | if (d == 'b') 183 | r = 2; 184 | if (!r) 185 | break; 186 | if (l) 187 | { 188 | xitoa((long) va_arg(arp, long), r, w); 189 | } 190 | else 191 | { 192 | if (r > 0) 193 | xitoa((unsigned long) va_arg(arp, int), r, w); 194 | else 195 | xitoa((long) va_arg(arp, int), r, w); 196 | } 197 | } 198 | 199 | va_end(arp); 200 | } 201 | 202 | void put_dump (const uint8_t *buff, uint32_t ofs, int cnt) 203 | { 204 | uint8_t n; 205 | 206 | xprintf("%08lX ", ofs); 207 | for (n = 0; n < cnt; n++) 208 | xprintf(" %02X", buff[n]); 209 | xputc(' '); 210 | for (n = 0; n < cnt; n++) 211 | { 212 | if ((buff[n] < 0x20) || (buff[n] >= 0x7F)) 213 | xputc('.'); 214 | else 215 | xputc(buff[n]); 216 | } 217 | xputc('\n'); 218 | } 219 | 220 | void get_line (char *buff, int len) 221 | { 222 | char c; 223 | int idx = 0; 224 | 225 | for (;;) 226 | { 227 | c = xgetc(); 228 | if (c == '\r') 229 | break; 230 | if ((c == '\b') && idx) 231 | { 232 | idx--; 233 | xputc(c); 234 | xputc(' '); 235 | xputc(c); // added by mthomas for Eclipse Terminal plug-in 236 | } 237 | if (((uint8_t) c >= ' ') && (idx < len - 1)) 238 | { 239 | buff[idx++] = c; 240 | xputc(c); 241 | } 242 | } 243 | buff[idx] = 0; 244 | xputc('\n'); 245 | } 246 | 247 | // function added by mthomas: 248 | int get_line_r (char *buff, int len, int* idx) 249 | { 250 | char c; 251 | int retval = 0; 252 | int myidx; 253 | 254 | if (xavail()) 255 | { 256 | myidx = *idx; 257 | c = xgetc(); 258 | if (c == '\r') 259 | { 260 | buff[myidx] = 0; 261 | xputc('\n'); 262 | retval = 1; 263 | } 264 | else 265 | { 266 | if ((c == '\b') && myidx) 267 | { 268 | myidx--; 269 | xputc(c); 270 | xputc(' '); 271 | xputc(c); // added by mthomas for Eclipse Terminal plug-in 272 | } 273 | if (((uint8_t) c >= ' ') && (myidx < len - 1)) 274 | { 275 | buff[myidx++] = c; 276 | xputc(c); 277 | } 278 | } 279 | *idx = myidx; 280 | } 281 | 282 | return retval; 283 | } 284 | -------------------------------------------------------------------------------- /x86/lwe_original.c: -------------------------------------------------------------------------------- 1 | #include "lwe_original.h" 2 | #include "stdio.h" 3 | 4 | void fwd_ntt(int a_0[], int a_1[]) 5 | { 6 | int i, j, k, m; 7 | int u1, t1, u2, t2; 8 | int primrt, omega; 9 | 10 | //primitive root = 5118 11 | //square_root = 1065 12 | 13 | for(m=2; m<=M/2; m=2*m) 14 | { 15 | 16 | if(m == 2) primrt=7680; //mpz_set_str(primrt,"7680",10); 17 | if(m == 4) primrt=4298; //mpz_set_str(primrt,"4298",10); 18 | if(m == 8) primrt=6468; //mpz_set_str(primrt,"6468",10); 19 | if(m == 16) primrt=849; //mpz_set_str(primrt,"849",10); 20 | if(m == 32) primrt=2138; //mpz_set_str(primrt,"2138",10); 21 | if(m == 64) primrt=3654; //mpz_set_str(primrt,"3654",10); 22 | if(m == 128) primrt=1714; //mpz_set_str(primrt,"1714",10); 23 | 24 | if(m == 2) omega = 4298; //mpz_set_str(omega,"4298",10); 25 | if(m == 4) omega = 6468; //mpz_set_str(omega,"6468",10); 26 | if(m == 8) omega = 849; //mpz_set_str(omega,"849",10); 27 | if(m == 16) omega = 2138; //mpz_set_str(omega,"2138",10); 28 | if(m == 32) omega = 3654; //mpz_set_str(omega,"3654",10); 29 | if(m == 64) omega = 1714; //mpz_set_str(omega,"1714",10); 30 | if(m == 128) omega = 5118; //mpz_set_str(omega,"5118",10); 31 | 32 | 33 | for(j=0; j>16)); 87 | 88 | //r = rand(); 89 | //a_0[i] = mod(r); 90 | //r = rand(); 91 | //a_1[i] = mod(r); 92 | } 93 | 94 | fwd_ntt(a_0, a_1); 95 | } 96 | 97 | int compare2(int a_0[128],int a_1[128],uint16_t large[M]) 98 | { 99 | int j; 100 | for (j=0; j<128; j++) 101 | { 102 | if ((large[2*j]!=a_0[j]) || (large[2*j+1]!=a_1[j])) 103 | { 104 | printf("j=%d",j); 105 | return 0; 106 | break; 107 | } 108 | } 109 | 110 | return 1; 111 | } 112 | 113 | void knuth_yao( int e_0[], int e_1[]) 114 | { 115 | int r; 116 | int distance; 117 | int row, column; 118 | int sample_cntr; 119 | 120 | int bit, input; 121 | int index, sample, sample_msb, random; 122 | 123 | int integer_equivalent; 124 | int flag1; 125 | int ran; 126 | int sample_in_table; 127 | 128 | uint32_t rnd; 129 | int found; 130 | rnd=get_rand(); 131 | 132 | 133 | for(sample_cntr=0; sample_cntr<128; sample_cntr++) 134 | { 135 | e_0[sample_cntr] = knuth_yao_single_number(&rnd,&sample_in_table); 136 | e_1[sample_cntr] = knuth_yao_single_number(&rnd,&sample_in_table); 137 | /* 138 | flag1=1; 139 | rnd = rand(); 140 | index = rnd&0xff; 141 | sample = lut1[index]; //256 elements in lut1 142 | sample_msb = sample & 16; 143 | if(sample_msb==0) //lookup was successful 144 | { 145 | sample = sample & 0xf; 146 | if ((rnd>>8)&1) sample = (MODULUS - sample); //9th bit in rnd is the sign 147 | if(sample_cntr%2==1) e_1[sample_cntr/2] = sample; // mpz_set_ui(e_1[SAMPLE_COUNTER/2], sample); 148 | if(sample_cntr%2==0) e_0[sample_cntr/2] = sample; //mpz_set_ui(e_0[SAMPLE_COUNTER/2], sample); 149 | } 150 | else 151 | { 152 | distance = sample & 7; 153 | rnd = rnd >> 8; 154 | index = rnd&0xff; 155 | sample = lut2[index]; //224 elements in lut2 156 | sample_msb = sample & 32; 157 | if(sample_msb==0) // lookup was successful 158 | { 159 | sample = sample & 31; 160 | if ((rnd>>8)&1) sample = (MODULUS - sample); //9th bit in rnd is the sign 161 | if(sample_cntr%2==1) e_1[sample_cntr/2] = sample; //mpz_set_ui(e_1[SAMPLE_COUNTER/2], sample); 162 | if(sample_cntr%2==0) e_0[sample_cntr/2] = sample; //mpz_set_ui(e_0[SAMPLE_COUNTER/2], sample); 163 | } 164 | 165 | //Real knuth-yao 166 | if(sample_msb!=0) 167 | { 168 | //rnd = rnd >> 8; 169 | distance = sample & 15; 170 | found=0; 171 | rnd=rnd>>7; 172 | for(column=13; ((found==0) && (column<109)); column++) 173 | { 174 | if ((column==32)||(column==64)||(column==96)) 175 | { 176 | rnd=rand(); 177 | } 178 | else 179 | { 180 | rnd = rnd>>1; 181 | } 182 | distance = distance*2 + (rnd&1); 183 | 184 | //distance = distance*2 + rand()&1; 185 | 186 | // Read probability-column 0 and count the number of non-zeros 187 | for(row=54; row>=0; row--) 188 | { 189 | distance = distance - pmat[row][column]; 190 | if(distance<0) 191 | { 192 | if (rnd&1) 193 | sample = (MODULUS - row); 194 | else 195 | sample = row; 196 | if(sample_cntr%2==1) e_1[sample_cntr/2] = sample; //mpz_set_ui(e_1[SAMPLE_COUNTER/2], sample); 197 | if(sample_cntr%2==0) e_0[sample_cntr/2] = sample; //mpz_set_ui(e_0[SAMPLE_COUNTER/2], sample); 198 | found=1; 199 | 200 | break; 201 | } 202 | } 203 | //rnd = rnd >> 1; 204 | } 205 | } 206 | }*/ 207 | 208 | // if (sample_cntr==2) 209 | // break; 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/lwe_arm.c: -------------------------------------------------------------------------------- 1 | #include "lwe_arm.h" 2 | 3 | #include "global.h" 4 | #include "stdint.h" 5 | #include "stdlib.h" 6 | #include "lwe.h" 7 | 8 | 9 | void r1_gen_asm(uint16_t * a) 10 | { 11 | #ifdef USE_KNUTH_YAO_SHUFFLE 12 | knuth_yao_shuffled_with_asm_optimization(a); 13 | #else 14 | knuth_yao_asm(a); 15 | #endif 16 | fwd_ntt_asm(a); 17 | } 18 | 19 | void key_gen_asm(uint16_t * a, uint16_t * r1, uint16_t * r2) 20 | { 21 | a_gen_asm(a); 22 | r1_gen_asm(r1); 23 | r2_gen_asm(r2); 24 | 25 | uint16_t tmp_a[M]; 26 | coefficient_mul_asm(tmp_a, a, r2); 27 | coefficient_sub_asm(r1, r1, tmp_a); 28 | rearrange_asm(r2); 29 | } 30 | 31 | void RLWE_dec_asm(uint16_t * c1, uint16_t * c2, uint16_t * r2) 32 | { 33 | // c1 <-- c1*r2 + c2 34 | coefficient_mul_add_asm(c1,c1,r2,c2); 35 | 36 | inv_ntt_asm(c1); //inv_ntt2(c1); 37 | } 38 | 39 | void RLWE_enc_asm(uint16_t * a, uint16_t * c1, uint16_t * c2, uint16_t * m, uint16_t * p) 40 | { 41 | uint16_t encoded_m[M]; 42 | 43 | encode_message_asm(encoded_m,m); //for(i=0; i>16)&0xffff) * QBY2)<<16); 44 | 45 | #ifdef USE_PARALLEL 46 | #ifdef USE_KNUTH_YAO_SHUFFLE 47 | knuth_yao_shuffled_with_asm_optimization((uint16_t *)fixed_data1); 48 | knuth_yao_shuffled_with_asm_optimization((uint16_t *)fixed_data2); 49 | knuth_yao_shuffled_with_asm_optimization((uint16_t *)fixed_data3); 50 | #else 51 | knuth_yao_asm(fixed_data1); 52 | knuth_yao_asm(fixed_data2); 53 | knuth_yao_asm(fixed_data3); 54 | #endif 55 | 56 | coefficient_add_asm((uint16_t *)fixed_data3, (uint16_t *)fixed_data3, (uint16_t *)encoded_m); // e3 <-- e3 + m 57 | 58 | fwd_ntt_parallel_asm(fixed_data1); //Uses fixed_data1+fixed_data2+fixed_data3. It knows that there is an offset of 0x200 between each consecutive item 59 | 60 | // m (c1) <-- e2 + a*e1 61 | coefficient_mul_add_asm((uint16_t *)c1,(uint16_t *)a,(uint16_t *)fixed_data1,(uint16_t *)fixed_data2); 62 | 63 | //c2 <-- e3 + p*e1 64 | coefficient_mul_add_asm((uint16_t *)c2,(uint16_t *)p,(uint16_t *)fixed_data1,(uint16_t *)fixed_data3); 65 | 66 | #else 67 | uint32_t e1[M], e2[M], e3[M], tmp_m[M/2];; 68 | knuth_yao_asm(e1); 69 | knuth_yao_asm(e2); 70 | knuth_yao_asm(e3); 71 | 72 | coefficient_add_asm((uint16_t *)e3, (uint16_t *)e3, (uint16_t *)encoded_m); // e3 <-- e3 + m 73 | 74 | fwd_ntt_asm(e1); 75 | fwd_ntt_asm(e2); 76 | fwd_ntt_asm(e3); 77 | 78 | coefficient_mul_asm(tmp_m,a,e1); //tmp_m <-- a*e1 79 | coefficient_add_asm((uint16_t *)c1, (uint16_t *)e2, (uint16_t *)tmp_m); // c1 <-- e2 <-- e2 + a*e1(tmp_m); 80 | coefficient_mul_asm(tmp_m,p,e1); // tmp_mm <-- p*e1 81 | coefficient_add_asm(c2, e3, tmp_m); // c2< <-- e3 <-- e3 + p*e1 82 | #endif 83 | 84 | rearrange_asm(c1); 85 | rearrange_asm(c2); 86 | } 87 | 88 | void message_gen_asm(uint16_t * m) 89 | { 90 | int i; 91 | for(i=0;i>16)&0xffff)+(((in[i+1]>>16)&0xffff)<<16); 109 | } 110 | } 111 | 112 | /* 113 | void rearrange_for_final_test_asm(uint16_t in[M],uint16_t out[M]) 114 | { 115 | int i; 116 | 117 | for (i=0; i>16)&0xffff)+(((in[i+1]>>16)&0xffff)<<16); 125 | out[i/2+M/4]=in[i+1]+in[i+3]; 126 | } 127 | }*/ 128 | 129 | void insert_lowval(uint32_t * a, uint32_t b) 130 | { 131 | *a = ((b)&0xffff) + ((*a)&0xffff0000); 132 | } 133 | 134 | void insert_highval(uint32_t * a, uint32_t b) 135 | { 136 | *a = ((b)<<16) + ((*a)&0xffff); 137 | } 138 | 139 | void bitreverse_asm(uint32_t a[M]) 140 | { 141 | //TODO: Convert this routine to take a uint16_t * input 142 | int i; 143 | int bit1, bit2, bit3, bit4, bit5, bit6, bit7, bit8, swp_index; 144 | int q1, r1, q2, r2; 145 | int temp; 146 | 147 | for(i=0; i>1)%2; 151 | bit3 = (i>>2)%2; 152 | bit4 = (i>>3)%2; 153 | bit5 = (i>>4)%2; 154 | bit6 = (i>>5)%2; 155 | bit7 = (i>>6)%2; 156 | bit8 = (i>>7)%2; 157 | 158 | q1 = i/2; 159 | r1 = i%2; 160 | #ifdef NTT512 161 | int bit9 = (i>>8)%2; 162 | swp_index = bit1*256 + bit2*128 + bit3*64 + bit4*32 + bit5*16 + bit6*8 + bit7*4 + bit8*2 + bit9; 163 | #else 164 | swp_index = bit1*128 + bit2*64 + bit3*32 + bit4*16 + bit5*8 + bit6*4 + bit7*2 + bit8; 165 | #endif 166 | q2 = swp_index/2; 167 | r2 = swp_index%2; 168 | 169 | if(swp_index>i) 170 | { 171 | if(r2==0) temp = a[q2]&0xffff; 172 | if(r2==1) temp = (a[q2]>>16)&0xffff; 173 | if(r2==0 && r1==0) insert_lowval(&a[q2],a[q1]);//a[2*q2] = a[2*q1]; 174 | if(r2==0 && r1==1) insert_lowval(&a[q2],(a[q1]>>16));//a[2*q2] = a[2*q1+1]; 175 | if(r2==1 && r1==0) insert_highval(&a[q2],a[q1]);//a[2*q2+1] = a[2*q1]; 176 | if(r2==1 && r1==1) insert_highval(&a[q2],(a[q1]>>16));//a[2*q2+1] = a[2*q1+1]; 177 | if(r1==0) insert_lowval(&a[q1],temp);//a[2*q1] = temp; 178 | if(r1==1) insert_highval(&a[q1],temp);//a[2*q1+1] = temp; 179 | } 180 | } 181 | } 182 | 183 | void ntt_multiply_asm(uint16_t * a, uint16_t * b, uint16_t * out) 184 | { 185 | fwd_ntt_asm(a); 186 | fwd_ntt_asm(b); 187 | 188 | coefficient_mul_asm(out,a,b); 189 | rearrange_asm(out); 190 | inv_ntt_asm(out); 191 | } 192 | 193 | void knuth_yao_shuffled_with_asm_optimization(uint16_t * out) 194 | { 195 | int counter2 = knuth_yao_asm_shuffle(out); 196 | //xprintf("counter2=%d\n",counter2); 197 | while (counter2 5 | 6 | #include "comm.h" 7 | 8 | #define MAX_STRLEN 12 // this is the maximum string length of our string in characters 9 | volatile char received_string[MAX_STRLEN+1]; // this will hold the recieved string 10 | 11 | /* This funcion initializes the USART1 peripheral 12 | * 13 | * Arguments: baudrate --> the baudrate at which the USART is 14 | * supposed to operate 15 | */ 16 | void init_USART1(uint32_t baudrate){ 17 | 18 | /* This is a concept that has to do with the libraries provided by ST 19 | * to make development easier the have made up something similar to 20 | * classes, called TypeDefs, which actually just define the common 21 | * parameters that every peripheral needs to work correctly 22 | * 23 | * They make our life easier because we don't have to mess around with 24 | * the low level stuff of setting bits in the correct registers 25 | */ 26 | GPIO_InitTypeDef GPIO_InitStruct; // this is for the GPIO pins used as TX and RX 27 | USART_InitTypeDef USART_InitStruct; // this is for the USART1 initilization 28 | NVIC_InitTypeDef NVIC_InitStructure; // this is used to configure the NVIC (nested vector interrupt controller) 29 | 30 | /* enable APB2 peripheral clock for USART1 31 | * note that only USART1 and USART6 are connected to APB2 32 | * the other USARTs are connected to APB1 33 | */ 34 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 35 | 36 | /* enable the peripheral clock for the pins used by 37 | * USART1, PB6 for TX and PB7 for RX 38 | */ 39 | RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); 40 | 41 | /* This sequence sets up the TX and RX pins 42 | * so they work correctly with the USART1 peripheral 43 | */ 44 | GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; // Pins 6 (TX) and 7 (RX) are used 45 | GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; // the pins are configured as alternate function so the USART peripheral has access to them 46 | GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; // this defines the IO speed and has nothing to do with the baudrate! 47 | GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // this defines the output type as push pull mode (as opposed to open drain) 48 | GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; // this activates the pullup resistors on the IO pins 49 | GPIO_Init(GPIOB, &GPIO_InitStruct); // now all the values are passed to the GPIO_Init() function which sets the GPIO registers 50 | 51 | /* The RX and TX pins are now connected to their AF 52 | * so that the USART1 can take over control of the 53 | * pins 54 | */ 55 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); // 56 | GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); 57 | 58 | /* Now the USART_InitStruct is used to define the 59 | * properties of USART1 60 | */ 61 | USART_InitStruct.USART_BaudRate = baudrate; // the baudrate is set to the value we passed into this init function 62 | USART_InitStruct.USART_WordLength = USART_WordLength_8b;// we want the data frame size to be 8 bits (standard) 63 | USART_InitStruct.USART_StopBits = USART_StopBits_1; // we want 1 stop bit (standard) 64 | USART_InitStruct.USART_Parity = USART_Parity_No; // we don't want a parity bit (standard) 65 | USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // we don't want flow control (standard) 66 | USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // we want to enable the transmitter and the receiver 67 | USART_Init(USART1, &USART_InitStruct); // again all the properties are passed to the USART_Init function which takes care of all the bit setting 68 | 69 | 70 | /* Here the USART1 receive interrupt is enabled 71 | * and the interrupt controller is configured 72 | * to jump to the USART1_IRQHandler() function 73 | * if the USART1 receive interrupt occurs 74 | */ 75 | 76 | /* 77 | * Uncomment this block of code to enable interrupt-based USART1 78 | USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // enable the USART1 receive interrupt 79 | 80 | NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // we want to configure the USART1 interrupts 81 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;// this sets the priority group of the USART1 interrupts 82 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group 83 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART1 interrupts are globally enabled 84 | NVIC_Init(&NVIC_InitStructure); // the properties are passed to the NVIC_Init function which takes care of the low level stuff 85 | */ 86 | 87 | // finally this enables the complete USART1 peripheral 88 | USART_Cmd(USART1, ENABLE); 89 | } 90 | 91 | /* This function is used to transmit a string of characters via 92 | * the USART specified in USARTx. 93 | * 94 | * It takes two arguments: USARTx --> can be any of the USARTs e.g. USART1, USART2 etc. 95 | * (volatile) char *s is the string you want to send 96 | * 97 | * Note: The string has to be passed to the function as a pointer because 98 | * the compiler doesn't know the 'string' data type. In standard 99 | * C a string is just an array of characters 100 | * 101 | * Note 2: At the moment it takes a volatile char because the received_string variable 102 | * declared as volatile char --> otherwise the compiler will spit out warnings 103 | * */ 104 | void USART_puts(USART_TypeDef* USARTx, volatile char *s){ 105 | 106 | while(*s){ 107 | // wait until data register is empty 108 | while( !(USARTx->SR & 0x00000040) ); 109 | USART_SendData(USARTx, *s); 110 | *s++; 111 | } 112 | } 113 | 114 | // this is the interrupt request handler (IRQ) for ALL USART1 interrupts 115 | void USART1_IRQHandler(void){ 116 | 117 | // check if the USART1 receive interrupt flag was set 118 | if( USART_GetITStatus(USART1, USART_IT_RXNE) ){ 119 | 120 | static uint8_t cnt = 0; // this counter is used to determine the string length 121 | char t = USART1->DR; // the character from the USART1 data register is saved in t 122 | 123 | /* check if the received character is not the LF character (used to determine end of string) 124 | * or the if the maximum string length has been been reached 125 | */ 126 | if( (t != '\n') && (cnt < MAX_STRLEN) ){ 127 | received_string[cnt] = t; 128 | cnt++; 129 | } 130 | else{ // otherwise reset the character counter and print the received string 131 | cnt = 0; 132 | USART_puts(USART1, received_string); 133 | } 134 | } 135 | } 136 | 137 | 138 | int comm_test (void) 139 | { 140 | /* 141 | //return (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE ) == RESET) ? 0 : 1; 142 | return ((USARTx ->SR & USART_FLAG_RXNE )!= RESET);*/ 143 | } 144 | 145 | unsigned char comm_get (void) 146 | { 147 | 148 | //USART_ClearFlag(USARTx, USART_FLAG_ORE ); // Reset overrun error flag, what are we going to do...? 149 | USART1 ->SR = (uint16_t) ~USART_FLAG_ORE; 150 | 151 | while ((USART1 ->SR & USART_FLAG_RXNE )== RESET) 152 | { 153 | } 154 | 155 | return (unsigned char) (USART1 ->DR & (uint16_t) 0x01FF); 156 | } 157 | 158 | void comm_put (unsigned char d) 159 | { 160 | /* 161 | //while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE ) == RESET) 162 | while ((USARTx ->SR & USART_FLAG_TXE )== RESET) 163 | { 164 | } 165 | 166 | //USART_SendData(USARTx, (uint16_t) d); 167 | USARTx ->DR = (d & (uint16_t) 0x01FF);*/ 168 | 169 | while(!(USART1->SR & 0x00000040)); 170 | USART_SendData(USART1, d); 171 | } 172 | 173 | void comm_init (void) 174 | { 175 | init_USART1(9600); 176 | } 177 | 178 | 179 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/knuth_yao_asm.S: -------------------------------------------------------------------------------- 1 | 2 | #include "global.h" 3 | 4 | #ifdef USE_FAKE_GET_RAND 5 | #define GET_RAND\ 6 | ldr r0, =g_fake_rand;\ 7 | ldr r0, [r0];\ 8 | orr r0, #0x80000000; 9 | #else 10 | #ifdef USE_TRNG 11 | #define GET_RAND\ 12 | ldr r0, =#RNG_ADDR;\ 13 | ldr r0, [r0, #8];\ 14 | orr r0, #0x80000000; 15 | #else 16 | #define GET_RAND\ 17 | push {r1,r2,r3,lr};\ 18 | bl rand;\ 19 | orr r0, #0x80000000;\ 20 | pop {r1,r2,r3,lr}; 21 | #endif 22 | #endif 23 | 24 | #define GET_RAND_IF_NECESSARY(id)\ 25 | /*cbnz r0,id;*/;\ 26 | cmp r0,#NEW_RND_BOTTOM;\ 27 | bgt id;\ 28 | GET_RAND;\ 29 | id: 30 | 31 | //The GET_RAND2 trick is sometimes faster 32 | #ifdef USE_TRNG 33 | #define GET_RAND2(id)\ 34 | ble id;\ 35 | ittt le;\ 36 | ldrle r0, =#RNG_ADDR;\ 37 | ldrle r0, [r0, #8];\ 38 | orrle r0,#0x80000000; 39 | #else 40 | #define GET_RAND2(id)\ 41 | ble id;\ 42 | push {r1,r2,r3,lr};\ 43 | bl rand;\ 44 | orr r0,#0x80000000;\ 45 | pop {r1,r2,r3,lr}; 46 | #endif 47 | 48 | #define BIT_SCANNING(id,jump_label)\ 49 | id:;\ 50 | clz r7,r10;\ 51 | add r7,#1;\ 52 | lsl r10,r7;\ 53 | sub r3,r7;\ 54 | subs r6,#1;\ 55 | bmi jump_label;\ 56 | cmp r10,#0;\ 57 | bne id; 58 | 59 | .syntax unified 60 | .cpu cortex-m4 61 | .fpu softvfp 62 | .thumb 63 | 64 | .section .text 65 | 66 | .balign 2 67 | .thumb 68 | .thumb_func 69 | .code 16 70 | 71 | .global knuth_yao_asm 72 | .extern knuth_yao_asm 73 | .type knuth_yao_asm, %function 74 | knuth_yao_asm: 75 | stmdb sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} 76 | 77 | mov r11,r0 //Save *return_vals to r11 78 | 79 | //r0=rnd 80 | //r1=str return val index 81 | //r2=lut1 82 | //r3=lut1_lookup, lut2_lookup, sample,row (return values) 83 | //r4=tmp: sample_msb, index, column 84 | //r5=MODULUS 85 | //r6=distance (only used from lut2_lookup_continue) 86 | //r7=temp (clz) 87 | //r8=pmat_cols_small_low 88 | //r9=pmat_cols_small_high/lut2 89 | //r10=low,high 90 | //r11=*return_vals 91 | //r12=(M-1) 92 | //r14=result from every second (odd numbered) calculation 93 | 94 | ldr r2,=lut1 95 | ldr r5,=MODULUS 96 | #ifdef USE_SMALL_TABLES 97 | ldr r8,=pmat_cols_small_low2 98 | #else 99 | ldr r8,=pmat_cols_small_low 100 | #endif 101 | //ldr r9,=pmat_cols_small_high 102 | ldr r9,=lut2 103 | mov r1,#-1 104 | GET_RAND; //Get the initial random number 105 | //ldr r0, =#RNG_ADDR 106 | //ldr r0, [r0, #8] 107 | ldr r12,=#(M-1) 108 | 109 | knuth_yao_single: 110 | 111 | uxtb r4,r0 //r4 = index 112 | lsr r0,#8 //(*rnd)=(*rnd)>>8; 113 | 114 | GET_RAND_IF_NECESSARY(lookup_lut1) 115 | //ldr r2, =lut1 116 | ldrb r3, [r2,r4]; //sample //sample (r3) = lut1[index]; //256 elements in lut1 117 | 118 | lsrs r4,r3,#5 //sample_msb = sample & 16 = (2^4) = fifth bit 119 | bcs lut1_no_success 120 | 121 | lut1_success_continue: 122 | //lut1 lookup SUCCESS 123 | 124 | //NB: This was part of the original LWE1.c, but seems to be unneccesary: 125 | //and r3,r3,#31;//sample = sample & 0xf; 126 | 127 | lsrs r0,#1 //rnd (r0) = rnd >> 1 128 | bcc cleanup //rnd_rem-- in cleanup 129 | 130 | sub r3,r5,r3 ////sample (r3) = (MODULUS - sample); 131 | b cleanup //rnd_rem-- in cleanup 132 | 133 | lut1_no_success: 134 | //lut1 lookup FAIL: Now try lut2 lookup 135 | 136 | //Check if enough bits exist inside rnd 137 | clz r4,r0 138 | 139 | cmp r4,#NEW_RND_MID//cmp r4,#27 140 | ble lut2_lookup_continue 141 | GET_RAND 142 | 143 | lut2_lookup_continue: 144 | and r6,r3,#KN_DISTANCE1_MASK; //distance(r6) = sample(r3) & 7; 145 | and r4,r0,#0x1f //r4 = (*rnd)&0x1f 146 | add r4,r4,r6,lsl #5 //index (r4) = [(*rnd)&0x1f] (r4) + 32*distance(r6); 147 | 148 | lsr r0,#5; //(*rnd) = (*rnd)>>5; 149 | 150 | GET_RAND_IF_NECESSARY(lut2_lookup_continue2) 151 | 152 | ldrb r3, [r9,r4]; //sample (r3) = lut2[index]; //224 elements in lut2 153 | 154 | lsrs r4,r3,#6 //The sixth bit (2^5) represents the sample_msb 155 | bcs lut2_no_success_start_real_kn 156 | 157 | //lut2 SUCCESS! 158 | and r3,#31 //sample (r3) = sample & 31; 159 | 160 | lsrs r0,#1 161 | bcc cleanup //rnd_rem-- in cleanup 162 | 163 | sub r3,r5,r3 //if ((*rnd)&1) sample (r3) = (MODULUS - sample) 164 | b cleanup //rnd_rem-- in cleanup 165 | 166 | lut2_no_success_start_real_kn: 167 | //Now we perform bit scanning with knuth-yao 168 | and r6,r3,#15; //distance (r6) = sample(r3) & 15; 169 | 170 | //for(column=0; column>1; 178 | add r6,r10,r6,lsl #1 //distance (r6) = ((*rnd)&1) + distance*2 179 | 180 | GET_RAND_IF_NECESSARY(real_kn_low_loop_continue) 181 | 182 | ldr r10,[r8, r4, lsl #2]; //low(r10)=pmat_cols_small_low[column]; 183 | 184 | mov r3,#LOW_MSB_PLUS_ONE; 185 | BIT_SCANNING(real_kn_low_loop1,finished_exit) 186 | 187 | add r4,#1 188 | cmp r4,#HAMMING_TABLE_SIZE 189 | blt real_kn_low_loop 190 | //*******End of (big) inner loop******* 191 | 192 | //At this point we still haven't found the gaussian sample. 193 | //We now have to use both the high and low values to perform the sampling. 194 | #ifdef USE_SMALL_TABLES 195 | ldr r9,=pmat_cols_small_high3 196 | #else 197 | ldr r9,=pmat_cols_small_high 198 | #endif 199 | real_kn_high_loop: 200 | 201 | //for(column=HAMMING_TABLE_SIZE; (column<(109-13)); column++) { 202 | and r10,r0,#1 //r10=((*rnd)&1); 203 | lsr r0,#1 //(*rnd)(r0)=(*rnd)>>1; 204 | add r6,r10,r6,lsl #1 //distance (r6) = ((*rnd)&1) + distance*2 205 | 206 | GET_RAND_IF_NECESSARY(real_kn_high_loop_continue) 207 | 208 | //***********Start of outer high loop************** 209 | 210 | #ifdef USE_SMALL_TABLES 211 | //If we use pmat_cols_small_high3 here then we need to subtract HAMMING_TABLE_SIZE 212 | //from r4 to read the correct entry in pmat_cols_small_high3 213 | ldr r3,=#HAMMING_TABLE_SIZE 214 | sub r3,r4,r3 215 | ldr r10,[r9, r3, lsl #2]; //high(r10)=pmat_cols_small_high[column]; 216 | #else 217 | ldr r10,[r9, r4, lsl #2]; //high(r10)=pmat_cols_small_high[column]; 218 | #endif 219 | 220 | 221 | cmp r10,#0 222 | beq low_loop_cont 223 | 224 | //Skip BIT_SCANNING here because r10==0 225 | mov r3,#PMAT_MAX_ROW_ONE; 226 | BIT_SCANNING(real_kn_high_loop1,high_low_finished_exit) 227 | low_loop_cont: 228 | mov r3,#LOW_MSB_PLUS_ONE //e3 might not get set to LOW_MSB_PLUS_ONE if pmat_cols_small_high=0 229 | ldr r10,[r8, r4, lsl #2]; //low(r10)=pmat_cols_small_low[column]; 230 | BIT_SCANNING(low_loop,high_low_finished_exit) 231 | 232 | add r4,#1 //column(r4) ++ 233 | b real_kn_high_loop //No tests are necessary: the loop should end in here 234 | //***********End of outer high loop************** 235 | 236 | high_low_finished_exit: 237 | ldr r9,=lut2 //Store @lut2 inside r9 238 | 239 | finished_exit: 240 | //FINISHED: Exit! 241 | //NB: r3 is used as an input here! 242 | lsrs r0,#1 //r0 = random number 243 | bcc cleanup //rnd_rem-- in cleanup 244 | 245 | sub r3,r5,r3 //sample (r3) = (MODULUS - sample); //9th bit in rnd is the sign 246 | 247 | cleanup: 248 | clz r6,r0 249 | //cmp r6,#24 250 | cmp r6,#NEW_RND_LARGE 251 | /*ble knuth_yao_asm_done //if ((*rnd_rem)<8) 252 | GET_RAND*/ 253 | GET_RAND2(knuth_yao_asm_done) 254 | 255 | knuth_yao_asm_done: 256 | 257 | add r1,#1 258 | strh r3,[r11,r1,lsl #1] 259 | 260 | /* 261 | Old way: Combining the two coefficients into a single word before writing it to memory 262 | 263 | add r14,r3,r14,lsl #16 //We combine two results into a single word 264 | //Only write the result to memory if r1 is even 265 | lsrs r7,r1,#1 266 | it cc 267 | strcc r14,[r11,r1,lsl #1]; //Write combined_results (r14) to [r11] 268 | add r1,#1 269 | */ 270 | 271 | cmp r1,r12 //cmp r1,#(M-1) //Check if r1==256 272 | bne knuth_yao_single //Jump to knuth_yao_single 273 | 274 | ldmia.w sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc} 275 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/knuth_yao_asm_shuffle.S: -------------------------------------------------------------------------------- 1 | 2 | #include "global.h" 3 | 4 | #ifdef USE_FAKE_GET_RAND 5 | #define GET_RAND\ 6 | ldr r0, =g_fake_rand;\ 7 | ldr r0, [r0];\ 8 | orr r0, #0x80000000; 9 | #else 10 | #ifdef USE_TRNG 11 | #define GET_RAND\ 12 | ldr r0, =#RNG_ADDR;\ 13 | ldr r0, [r0, #8];\ 14 | orr r0, #0x80000000; 15 | #else 16 | #define GET_RAND\ 17 | push {r1,r2,r3,lr};\ 18 | bl rand;\ 19 | orr r0, #0x80000000;\ 20 | pop {r1,r2,r3,lr}; 21 | #endif 22 | #endif 23 | 24 | #define GET_RAND_IF_NECESSARY(id)\ 25 | /*cbnz r0,id;*/;\ 26 | cmp r0,#NEW_RND_BOTTOM;\ 27 | bgt id;\ 28 | GET_RAND;\ 29 | id: 30 | 31 | //The GET_RAND2 trick is sometimes faster 32 | #ifdef USE_TRNG 33 | #define GET_RAND2(id)\ 34 | ble id;\ 35 | ittt le;\ 36 | ldrle r0, =#RNG_ADDR;\ 37 | ldrle r0, [r0, #8];\ 38 | orrle r0,#0x80000000; 39 | #else 40 | #define GET_RAND2(id)\ 41 | ble id;\ 42 | push {r1,r2,r3,lr};\ 43 | bl rand;\ 44 | orr r0,#0x80000000;\ 45 | pop {r1,r2,r3,lr}; 46 | #endif 47 | 48 | #define BIT_SCANNING(id,jump_label)\ 49 | id:;\ 50 | clz r7,r10;\ 51 | add r7,#1;\ 52 | lsl r10,r7;\ 53 | sub r3,r7;\ 54 | subs r6,#1;\ 55 | bmi jump_label;\ 56 | cmp r10,#0;\ 57 | bne id; 58 | 59 | .syntax unified 60 | .cpu cortex-m4 61 | .fpu softvfp 62 | .thumb 63 | 64 | .section .text 65 | 66 | .balign 2 67 | .thumb 68 | .thumb_func 69 | .code 16 70 | 71 | .global knuth_yao_asm_shuffle 72 | .extern knuth_yao_asm_shuffle 73 | .type knuth_yao_asm_shuffle, %function 74 | knuth_yao_asm_shuffle: 75 | stmdb sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr} 76 | 77 | mov r11,r0 //Save *return_vals to r11 78 | 79 | //r0=rnd 80 | //r1=str return val index 81 | //r2=lut1 82 | //r3=lut1_lookup, lut2_lookup, sample,row (return values) 83 | //r4=tmp: sample_msb, index, column 84 | //r5=MODULUS 85 | //r6=distance (only used from lut2_lookup_continue) 86 | //r7=temp (clz) 87 | //r8=pmat_cols_small_low 88 | //r9=pmat_cols_small_high/lut2 89 | //r10=low,high 90 | //r11=*return_vals 91 | //r12=(M-1) 92 | //r14=result from every second (odd numbered) calculation 93 | 94 | ldr r2,=lut1 95 | ldr r5,=MODULUS 96 | #ifdef USE_SMALL_TABLES 97 | ldr r8,=pmat_cols_small_low2 98 | #else 99 | ldr r8,=pmat_cols_small_low 100 | #endif 101 | //ldr r9,=pmat_cols_small_high 102 | ldr r9,=lut2 103 | mov r1,#-1 104 | GET_RAND; //Get the initial random number 105 | //ldr r0, =#RNG_ADDR 106 | //ldr r0, [r0, #8] 107 | ldr r12,=#(M-1) 108 | 109 | knuth_yao_single: 110 | 111 | uxtb r4,r0 //r4 = index 112 | lsr r0,#8 //(*rnd)=(*rnd)>>8; 113 | 114 | GET_RAND_IF_NECESSARY(lookup_lut1) 115 | //ldr r2, =lut1 116 | ldrb r3, [r2,r4]; //sample //sample (r3) = lut1[index]; //256 elements in lut1 117 | 118 | lsrs r4,r3,#5 //sample_msb = sample & 16 = (2^4) = fifth bit 119 | bcs lut1_no_success 120 | 121 | lut1_success_continue: 122 | //lut1 lookup SUCCESS 123 | 124 | //NB: This was part of the original LWE1.c, but seems to be unneccesary: 125 | //and r3,r3,#31;//sample = sample & 0xf; 126 | 127 | lsrs r0,#1 //rnd (r0) = rnd >> 1 128 | bcc cleanup //rnd_rem-- in cleanup 129 | 130 | sub r3,r5,r3 ////sample (r3) = (MODULUS - sample); 131 | b cleanup //rnd_rem-- in cleanup 132 | 133 | lut1_no_success: 134 | //lut1 lookup FAIL: Now try lut2 lookup 135 | 136 | //Check if enough bits exist inside rnd 137 | clz r4,r0 138 | 139 | cmp r4,#NEW_RND_MID//cmp r4,#27 140 | ble lut2_lookup_continue 141 | GET_RAND 142 | 143 | lut2_lookup_continue: 144 | and r6,r3,#KN_DISTANCE1_MASK; //distance(r6) = sample(r3) & 7; 145 | and r4,r0,#0x1f //r4 = (*rnd)&0x1f 146 | add r4,r4,r6,lsl #5 //index (r4) = [(*rnd)&0x1f] (r4) + 32*distance(r6); 147 | 148 | lsr r0,#5; //(*rnd) = (*rnd)>>5; 149 | 150 | GET_RAND_IF_NECESSARY(lut2_lookup_continue2) 151 | 152 | ldrb r3, [r9,r4]; //sample (r3) = lut2[index]; //224 elements in lut2 153 | 154 | lsrs r4,r3,#6 //The sixth bit (2^5) represents the sample_msb 155 | bcs lut2_no_success_start_real_kn 156 | 157 | //lut2 SUCCESS! 158 | and r3,#31 //sample (r3) = sample & 31; 159 | 160 | lsrs r0,#1 161 | bcc cleanup //rnd_rem-- in cleanup 162 | 163 | sub r3,r5,r3 //if ((*rnd)&1) sample (r3) = (MODULUS - sample) 164 | b cleanup //rnd_rem-- in cleanup 165 | 166 | lut2_no_success_start_real_kn: 167 | //Now we perform bit scanning with knuth-yao 168 | and r6,r3,#15; //distance (r6) = sample(r3) & 15; 169 | 170 | //for(column=0; column>1; 178 | add r6,r10,r6,lsl #1 //distance (r6) = ((*rnd)&1) + distance*2 179 | 180 | GET_RAND_IF_NECESSARY(real_kn_low_loop_continue) 181 | 182 | ldr r10,[r8, r4, lsl #2]; //low(r10)=pmat_cols_small_low[column]; 183 | 184 | mov r3,#LOW_MSB_PLUS_ONE; 185 | BIT_SCANNING(real_kn_low_loop1,finished_exit) 186 | 187 | add r4,#1 188 | cmp r4,#HAMMING_TABLE_SIZE 189 | blt real_kn_low_loop 190 | //*******End of (big) inner loop******* 191 | 192 | //At this point we still haven't found the gaussian sample. 193 | //We now have to use both the high and low values to perform the sampling. 194 | #ifdef USE_SMALL_TABLES 195 | ldr r9,=pmat_cols_small_high3 196 | #else 197 | ldr r9,=pmat_cols_small_high 198 | #endif 199 | real_kn_high_loop: 200 | 201 | //for(column=HAMMING_TABLE_SIZE; (column<(109-13)); column++) { 202 | and r10,r0,#1 //r10=((*rnd)&1); 203 | lsr r0,#1 //(*rnd)(r0)=(*rnd)>>1; 204 | add r6,r10,r6,lsl #1 //distance (r6) = ((*rnd)&1) + distance*2 205 | 206 | GET_RAND_IF_NECESSARY(real_kn_high_loop_continue) 207 | 208 | //***********Start of outer high loop************** 209 | 210 | #ifdef USE_SMALL_TABLES 211 | //If we use pmat_cols_small_high3 here then we need to subtract HAMMING_TABLE_SIZE 212 | //from r4 to read the correct entry in pmat_cols_small_high3 213 | ldr r3,=#HAMMING_TABLE_SIZE 214 | sub r3,r4,r3 215 | ldr r10,[r9, r3, lsl #2]; //high(r10)=pmat_cols_small_high[column]; 216 | #else 217 | ldr r10,[r9, r4, lsl #2]; //high(r10)=pmat_cols_small_high[column]; 218 | #endif 219 | 220 | 221 | cmp r10,#0 222 | beq low_loop_cont 223 | 224 | //Skip BIT_SCANNING here because r10==0 225 | mov r3,#PMAT_MAX_ROW_ONE; 226 | BIT_SCANNING(real_kn_high_loop1,high_low_finished_exit) 227 | low_loop_cont: 228 | mov r3,#LOW_MSB_PLUS_ONE //e3 might not get set to LOW_MSB_PLUS_ONE if pmat_cols_small_high=0 229 | ldr r10,[r8, r4, lsl #2]; //low(r10)=pmat_cols_small_low[column]; 230 | BIT_SCANNING(low_loop,high_low_finished_exit) 231 | 232 | add r4,#1 //column(r4) ++ 233 | b real_kn_high_loop //No tests are necessary: the loop should end in here 234 | //***********End of outer high loop************** 235 | 236 | high_low_finished_exit: 237 | ldr r9,=lut2 //Store @lut2 inside r9 238 | 239 | finished_exit: 240 | //FINISHED: Exit! 241 | //NB: r3 is used as an input here! 242 | lsrs r0,#1 //r0 = random number 243 | //TODO: Here we need to bcc to a routine that writes the output to location r12 244 | bcc cleanup_no_lut //rnd_rem-- in cleanup 245 | sub r3,r5,r3 //sample (r3) = (MODULUS - sample); //9th bit in rnd is the sign 246 | b cleanup_no_lut 247 | 248 | cleanup: 249 | clz r6,r0 250 | cmp r6,#NEW_RND_LARGE 251 | GET_RAND2(knuth_yao_asm_done) 252 | 253 | knuth_yao_asm_done: 254 | 255 | //add r14,r3,r14,lsl #16 //We combine two results into a single word 256 | 257 | //Only write the result to memory if r1 is even 258 | //lsrs r7,r1,#1 259 | //it cc 260 | //strcc r14,[r11,r1,lsl #1]; //Write combined_results (r14) to [r11] 261 | 262 | add r1,#1 263 | strh r3,[r11,r1,lsl #1] 264 | cmp r1,r12 //cmp r1,#(M-1) //Check if r1==256 265 | bne knuth_yao_single //Jump to knuth_yao_single 266 | 267 | add r0,r12,#1 //return counter2 268 | ldmia.w sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc} 269 | 270 | .global cleanup_no_lut 271 | .extern cleanup_no_lut 272 | .type cleanup_no_lut, %function 273 | cleanup_no_lut: 274 | clz r6,r0 275 | cmp r6,#NEW_RND_LARGE 276 | GET_RAND2(knuth_yao_asm_done_no_lut) 277 | 278 | knuth_yao_asm_done_no_lut: 279 | 280 | //add r14,r3,r14,lsl #16 //We combine two results into a single word 281 | 282 | //Only write the result to memory if r1 is even 283 | //lsrs r7,r1,#1 284 | //it cc 285 | //strcc r14,[r11,r1,lsl #1]; //Write combined_results (r14) to [r11] 286 | 287 | //add r1,#1 288 | strh r3,[r11,r12,lsl #1] 289 | sub r12,#1 290 | cmp r1,r12 //cmp r1,#(M-1) //Check if r1==256 291 | bne knuth_yao_single //Jump to knuth_yao_single 292 | 293 | add r0,r12,#1 //return counter2 294 | ldmia.w sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc} 295 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/a.txt: -------------------------------------------------------------------------------- 1 | Script started on Thu 04 Sep 2014 04:51:46 PM CEST 2 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ svn cimake uartgdb-serveruartsvn cimake uartgdb-servercleangdb-servergrep coefficient_add_asm *screen /dev/ttyUSB0 115200make programscreen /dev/ttyUSB0 115200 3 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ cat a,txt 4 | cat: a,txt: No such file or directory 5 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ cat a,txttxt.txt 6 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls 7 | total 1.2M 8 | drwxr-xr-x. 3 rdeclerc cosic 4.0K Sep 4 16:50 . 9 | drwxr-xr-x. 24 rdeclerc cosic 4.0K Sep 3 15:31 .. 10 | drwxr-xr-x. 6 rdeclerc cosic 4.0K Sep 4 11:30 .svn 11 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 12 | -rw-r--r--. 1 rdeclerc cosic 971 Sep 3 14:03 code_size.py 13 | -rwxr-xr-x. 1 rdeclerc cosic 6.8K Sep 3 14:03 comm.c 14 | -rwxr-xr-x. 1 rdeclerc cosic 312 Sep 3 14:03 comm.h 15 | -rw-r--r--. 1 rdeclerc cosic 3.8K Sep 3 15:16 .cproject 16 | -rw-r--r--. 1 rdeclerc cosic 259 Sep 3 14:03 global.c 17 | -rw-r--r--. 1 rdeclerc cosic 1.6K Sep 4 16:49 global.h 18 | -rw-r--r--. 1 rdeclerc cosic 1.3K Sep 3 14:49 global.h~ 19 | -rw-r--r--. 1 rdeclerc cosic 7.0K Sep 3 14:54 knuth_yao_asm_broken.S 20 | -rw-r--r--. 1 rdeclerc cosic 6.7K Sep 3 15:57 knuth_yao_asm_good.S 21 | -rw-r--r--. 1 rdeclerc cosic 203 Sep 3 14:03 knuth_yao_asm.h 22 | -rw-r--r--. 1 rdeclerc cosic 6.6K Sep 4 14:45 knuth_yao_asm.S 23 | -rwxr-xr-x. 1 rdeclerc cosic 45K Sep 4 15:28 luts.h 24 | -rwxr-xr-x. 1 rdeclerc cosic 14K Sep 4 15:02 lwe.c 25 | -rw-r--r--. 1 rdeclerc cosic 22K Sep 3 14:03 lwe.c~ 26 | -rwxr-xr-x. 1 rdeclerc cosic 1.8K Sep 4 11:27 lwe.h 27 | -rwxr-xr-x. 1 rdeclerc cosic 109K Sep 4 16:50 main.bin 28 | -rw-r--r--. 1 rdeclerc cosic 7.5K Sep 4 16:49 main.c 29 | -rw-r--r--. 1 rdeclerc cosic 23K Sep 3 14:56 main.c~ 30 | -rwxr-xr-x. 1 rdeclerc cosic 377K Sep 4 16:50 main.elf 31 | -rw-r--r--. 1 rdeclerc cosic 305K Sep 4 16:50 main.hex 32 | -rwxr-xr-x. 1 rdeclerc cosic 3.0K Sep 4 10:25 Makefile 33 | -rw-r--r--. 1 rdeclerc cosic 814 Sep 3 14:03 .project 34 | -rw-r--r--. 1 rdeclerc cosic 9.2K Sep 4 11:33 speed_test.c 35 | -rw-r--r--. 1 rdeclerc cosic 98 Sep 3 14:03 speed_test.h 36 | -rw-r--r--. 1 rdeclerc cosic 24K Sep 3 14:03 startup_stm32f40xx.s 37 | -rw-r--r--. 1 rdeclerc cosic 3.7K Sep 3 14:03 stm32f4xx_conf.h 38 | -rw-r--r--. 1 rdeclerc cosic 4.5K Sep 3 14:03 stm32f4xx_it.c 39 | -rw-r--r--. 1 rdeclerc cosic 2.2K Sep 3 14:03 stm32f4xx_it.h 40 | -rwxr-xr-x. 1 rdeclerc cosic 4.9K Sep 3 14:03 stm32_flash.ld 41 | -rw-r--r--. 1 rdeclerc cosic 22K Sep 3 14:03 system_stm32f4xx.c 42 | -rwxr-xr-x. 1 rdeclerc cosic 4.2K Sep 3 14:03 term_io.c 43 | -rwxr-xr-x. 1 rdeclerc cosic 545 Sep 3 14:03 term_io.h 44 | -rw-r--r--. 1 rdeclerc cosic 4.4K Sep 3 17:01 test_asm.c 45 | -rwxr-xr-x. 1 rdeclerc cosic 1.8K Sep 4 10:31 test_asm.h 46 | -rw-r--r--. 1 rdeclerc cosic 27K Sep 4 11:32 test_asm.S 47 | -rw-r--r--. 1 rdeclerc cosic 21K Sep 4 11:32 throw_away.c 48 | -rw-r--r--. 1 rdeclerc cosic 13K Sep 4 14:42 unit_test.c 49 | -rw-r--r--. 1 rdeclerc cosic 76 Sep 4 10:25 unit_test.h 50 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 51 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 52 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt cat a.txt,txtscreen /dev/ttyUSB0 115200 53 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200ls a.txt cat a.txt,txtscreen /dev/ttyUSB0 115200vn cimake uartgdb-serveruartsvn cimake uartgdb-serveruartsvn cicreen /dev/ttyUSB0 115200cat a,txt.txtls a.txt screen /dev/ttyUSB0 115200SCRIPT ^C 54 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ script a.txt 55 | Script started, file is a.txt 56 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ svn cimake uartgdb-serveruartsvn cimake uartgdb-servercleangdb-servergrep coefficient_add_asm *screen /dev/ttyUSB0 115200make programscreen /dev/ttyUSB0 115200 57 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 58 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 59 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 60 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 61 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 62 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 63 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 64 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 65 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 66 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 67 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 68 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 69 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 70 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 71 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt 72 | -rw-r--r--. 1 rdeclerc cosic 0 Sep 4 16:50 a.txt 73 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ls a.txt screen /dev/ttyUSB0 115200vn cimake uartgdb-serveruartsvn cimake uartgdb-server^C 74 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ script a.txt 75 | Script started, file is a.txt 76 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ svn cimake uartgdb-serveruartsvn cimake uartgdb-servercleangdb-servergrep coefficient_add_asm *screen /dev/ttyUSB0 115200make programscreen /dev/ttyUSB0 115200 77 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 78 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ kscreen /dev/ttyUSB0 115200 79 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 80 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 81 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 82 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 83 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 84 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 1152001 115200 85 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB1 115200 86 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB1 115200 87 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB1 1152000 88 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 89 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 90 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 91 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 92 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ screen /dev/ttyUSB0 115200 93 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ps aux | grep Serial 94 | 223:rdeclerc 13808 0.0 0.0 103260 916 pts/8 S+ 16:59 0:00 grep -I --line-number --color=always Serial 95 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ps aux | grep SerialerialrialialallMonitor 96 | 223:rdeclerc 13847 0.0 0.0 103260 916 pts/8 S+ 16:59 0:00 grep -I --line-number --color=always Monitor 97 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ ps aux | grep Monitorscreen 98 | 192:rdeclerc 10598 0.0 0.7 295728 28000 ? Ss Aug11 1:28 gnome-screensaver 99 | 214:rdeclerc 12884 0.0 0.0 129692 324 pts/0 S+ Aug11 0:04 screen -S 1 100 | 223:rdeclerc 13866 0.0 0.0 103264 1000 pts/8 S+ 16:59 0:00 grep -I --line-number --color=always screen 101 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ exit 102 | exit 103 | Script done, file is a.txt 104 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ exit 105 | exit 106 | Script done, file is a.txt 107 | [rdeclerc@judas stm32f407-discovery-rlwe-r550]$ exit 108 | exit 109 | 110 | Script done on Thu 04 Sep 2014 04:59:16 PM CEST 111 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/speed_test.c: -------------------------------------------------------------------------------- 1 | #include "speed_test.h" 2 | #include "stdint.h" 3 | #include 4 | #include "stm32f4xx.h" 5 | #include "core_cm4.h" 6 | #include "term_io.h" 7 | #include "stdlib.h" 8 | #include "lwe.h" 9 | #include "lwe_arm.h" 10 | 11 | 12 | 13 | void printDuration(uint32_t startTime, uint32_t stopTime, int repeatCount, uint64_t offset_cycles, int report_samples) 14 | { 15 | uint32_t total_cycles = (stopTime - startTime) - offset_cycles; 16 | uint32_t average_cycles = total_cycles/repeatCount; 17 | if (report_samples==1) 18 | { 19 | 20 | xprintf("[Timing] Avg: %u cycles, %d cycles/sample\n", average_cycles, (average_cycles)/M); 21 | } 22 | else 23 | { 24 | xprintf("[Timing] Avg: %u cycles\n", average_cycles); 25 | } 26 | 27 | } 28 | 29 | void speed_test() 30 | { 31 | int i; 32 | uint16_t small1[M],small2[M],small3[M],small4[M],small5[M]; 33 | 34 | // Allocate variables 35 | uint32_t startTime, stopTime; 36 | 37 | //startTime = clock(); // Get the start time 38 | //stopTime = clock(); // Get the stop time 39 | 40 | CoreDebug->DEMCR = CoreDebug->DEMCR | 0x01000000; //*SCB_DEMCR = *SCB_DEMCR | 0x01000000; 41 | DWT->CYCCNT=0;//*DWT_CYCCNT = 0; // reset the counter 42 | DWT->CTRL=DWT->CTRL | 1;//*DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter 43 | 44 | 45 | startTime = DWT->CYCCNT; // Get the start time 46 | stopTime = DWT->CYCCNT; // Get the stop time 47 | uint64_t offset_cycles = (uint32_t)(stopTime-startTime); 48 | 49 | xprintf("offset_cycles:%u\n",(uint32_t)offset_cycles); 50 | stopTime = DWT->CYCCNT; // Get the stop time 51 | 52 | #ifdef PERFORM_BIG_SPEED_TESTS 53 | srand(1000); 54 | DWT->CYCCNT=0; 55 | startTime = DWT->CYCCNT; // Get the start time 56 | for (i=0; iCYCCNT; // Get the end time 61 | xprintf("knuth_yao_shuffled_with_asm_optimization:"); 62 | printDuration(startTime, stopTime,SPEED_TEST_BIG_LOOPS,offset_cycles,true); 63 | 64 | srand(1000); 65 | DWT->CYCCNT=0; 66 | startTime = DWT->CYCCNT; // Get the start time 67 | for (i=0; iCYCCNT; // Get the end time 72 | xprintf("knuth_yao_asm_shuffle:"); 73 | printDuration(startTime, stopTime, SPEED_TEST_BIG_LOOPS,offset_cycles,true); 74 | 75 | 76 | srand(1000); 77 | DWT->CYCCNT=0; 78 | startTime = DWT->CYCCNT; // Get the start time 79 | for (i=0; iCYCCNT; // Get the end time 84 | xprintf("knuth_yao_asm:"); 85 | printDuration(startTime, stopTime, SPEED_TEST_BIG_LOOPS,offset_cycles,true); 86 | 87 | srand(1000); 88 | DWT->CYCCNT=0; 89 | startTime = DWT->CYCCNT; // Get the start time 90 | for (i=0; iCYCCNT; // Get the end time 95 | xprintf("ntt_multiply_asm:"); 96 | printDuration(startTime, stopTime, SPEED_TEST_BIG_LOOPS,offset_cycles,false); 97 | 98 | srand(1000); 99 | DWT->CYCCNT=0; 100 | startTime = DWT->CYCCNT; // Get the start time 101 | for (i=0; iCYCCNT; // Get the end time 106 | xprintf("RLWE_enc_asm:"); 107 | printDuration(startTime, stopTime, SPEED_TEST_BIG_LOOPS,offset_cycles,false); 108 | 109 | srand(1000); 110 | DWT->CYCCNT=0; 111 | startTime = DWT->CYCCNT; // Get the start time 112 | for (i=0; iCYCCNT; // Get the end time 117 | xprintf("RLWE_dec_asm:"); 118 | printDuration(startTime, stopTime, SPEED_TEST_BIG_LOOPS,offset_cycles,false); 119 | 120 | srand(1000); 121 | DWT->CYCCNT=0; 122 | startTime = DWT->CYCCNT; // Get the start time 123 | for (i=0; iCYCCNT; // Get the end time 128 | xprintf("key_gen_asm:"); 129 | printDuration(startTime, stopTime, SPEED_TEST_BIG_LOOPS,offset_cycles,false); 130 | 131 | 132 | 133 | #endif 134 | 135 | #ifdef PERFORM_MODULO_SPEED_TESTS 136 | int num,num16; 137 | srand(1000); 138 | DWT->CYCCNT=0; 139 | startTime = DWT->CYCCNT; // Get the start time 140 | for (i=0; iCYCCNT; // Get the end time 146 | xprintf("mod_asm_simd:"); 147 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 148 | 149 | srand(1000); 150 | DWT->CYCCNT=0; 151 | startTime = DWT->CYCCNT; // Get the start time 152 | for (i=0; iCYCCNT; // Get the end time 158 | xprintf("umod_asm:"); 159 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 160 | 161 | srand(1000); 162 | DWT->CYCCNT=0; 163 | startTime = DWT->CYCCNT; // Get the start time 164 | for (i=0; iCYCCNT; // Get the end time 170 | xprintf("umod_div_asm:"); 171 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 172 | 173 | srand(1000); 174 | DWT->CYCCNT=0; 175 | startTime = DWT->CYCCNT; // Get the start time 176 | for (i=0; iCYCCNT; // Get the end time 182 | xprintf("smod_asm:"); 183 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 184 | 185 | srand(1000); 186 | DWT->CYCCNT=0; 187 | startTime = DWT->CYCCNT; // Get the start time 188 | for (i=0; iCYCCNT; // Get the end time 198 | xprintf("mod_asm:"); 199 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 200 | 201 | srand(1000); 202 | DWT->CYCCNT=0; 203 | startTime = DWT->CYCCNT; // Get the start time 204 | for (i=0; iCYCCNT; // Get the end time 214 | xprintf("mod_asm2:"); 215 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 216 | 217 | srand(1000); 218 | DWT->CYCCNT=0; 219 | startTime = DWT->CYCCNT; // Get the start time 220 | for (i=0; iCYCCNT; // Get the end time 230 | xprintf("mod_asm3:"); 231 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 232 | 233 | srand(1000); 234 | DWT->CYCCNT=0; 235 | startTime = DWT->CYCCNT; // Get the start time 236 | for (i=0; iCYCCNT; // Get the end time 246 | xprintf("mod_asm4:"); 247 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 248 | 249 | srand(1000); 250 | DWT->CYCCNT=0; 251 | startTime = DWT->CYCCNT; // Get the start time 252 | for (i=0; iCYCCNT; // Get the end time 262 | xprintf("mod_asm5:"); 263 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 264 | 265 | #endif 266 | 267 | #ifdef PERFORM_SMALL_SPEED_TESTS 268 | 269 | srand(1000); 270 | DWT->CYCCNT=0; 271 | startTime = DWT->CYCCNT; // Get the start time 272 | for (i=0; iCYCCNT; // Get the end time 277 | xprintf("fwd_ntt2:"); 278 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS/100,offset_cycles,false); 279 | 280 | srand(1000); 281 | DWT->CYCCNT=0; 282 | startTime = DWT->CYCCNT; // Get the start time 283 | for (i=0; iCYCCNT; // Get the end time 288 | xprintf("fwd_ntt_parallel_asm:"); 289 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS/100,offset_cycles,false); 290 | 291 | 292 | srand(1000); 293 | DWT->CYCCNT=0; 294 | startTime = DWT->CYCCNT; // Get the start time 295 | for (i=0; iCYCCNT; // Get the end time 300 | xprintf("fwd_ntt_asm:"); 301 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS/100,offset_cycles,false); 302 | 303 | srand(1000); 304 | DWT->CYCCNT=0; 305 | startTime = DWT->CYCCNT; // Get the start time 306 | for (i=0; iCYCCNT; // Get the end time 311 | xprintf("inv_ntt_asm:"); 312 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS/100,offset_cycles,false); 313 | 314 | srand(1000); 315 | DWT->CYCCNT=0; 316 | startTime = DWT->CYCCNT; // Get the start time 317 | for (i=0; iCYCCNT; // Get the end time 322 | xprintf("coefficient_add_asm:"); 323 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS/100,offset_cycles,false); 324 | 325 | srand(1000); 326 | DWT->CYCCNT=0; 327 | startTime = DWT->CYCCNT; // Get the start time 328 | for (i=0; iCYCCNT; // Get the end time 333 | xprintf("coefficient_mul_asm:"); 334 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS/100,offset_cycles,false); 335 | 336 | /* 337 | srand(1000); 338 | startTime = DWT->CYCCNT; // Get the start time 339 | rnd=rand(); 340 | for (i=0x00000000; i<=SPEED_TEST_SMALL_LOOPS; i++) 341 | { 342 | num = knuth_yao_single_number_optimized(&rnd); 343 | } 344 | stopTime = DWT->CYCCNT; // Get the end time 345 | // Print cycles 346 | xprintf("knuth_yao_single_number_optimized:"); 347 | printDuration(startTime, stopTime, SPEED_TEST_SMALL_LOOPS,offset_cycles,false); 348 | */ 349 | #endif 350 | } 351 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/unit_test.c: -------------------------------------------------------------------------------- 1 | #include "global.h" 2 | #include "speed_test.h" 3 | #include "term_io.h" 4 | #include "unit_test.h" 5 | #include "lwe.h" 6 | #include "lwe_arm.h" 7 | #include "stdint.h" 8 | #include "stdlib.h" 9 | 10 | 11 | int compare_uint32(const void * a[2], const void * b[2]) 12 | { 13 | return ( *(uint32_t*)a - *(uint32_t*)b ); 14 | } 15 | 16 | int compare_uint16(const void * a[2], const void * b[2]) 17 | { 18 | return ( *(uint16_t*)a - *(uint16_t*)b ); 19 | } 20 | 21 | void convert_to_uint16_t_array(uint32_t *in, uint16_t *out) 22 | { 23 | int i; 24 | for (i=0; i>16)!=large2[1]) //check only the first element 104 | { 105 | xprintf("i=%d \n",i); 106 | fail=1; 107 | break; 108 | } 109 | } 110 | if (fail==1) 111 | { 112 | xprintf("FAIL i=%x\n",i); 113 | } 114 | else 115 | { 116 | xprintf("OK\n"); 117 | } 118 | #endif 119 | 120 | xputs("knuth_yao_shuffled: "); 121 | fail = 0; 122 | for (i = 0; i < UNIT_TEST_SMALL_LOOPS; i++) 123 | { 124 | if ((i%100)==0) 125 | xprintf("."); 126 | 127 | // Test knuth-yao 128 | srand(i * i); 129 | knuth_yao_shuffled(small1); 130 | 131 | srand(i * i); 132 | knuth_yao_shuffled_with_asm_optimization(small2); 133 | 134 | if (memcompare(small1, small2, M) != 1) 135 | { 136 | xprintf("knuth_yao_asm_shuffle fail i=%d\n",i); 137 | fail = 1; 138 | break; 139 | } 140 | 141 | qsort (small1, M, sizeof (uint16_t), compare_uint16); 142 | qsort (small2, M, sizeof (uint16_t), compare_uint16); 143 | if (memcompare(small2, small1, M) != 1) 144 | { 145 | xputs("knuth_yao_small fail"); 146 | fail = 1; 147 | break; 148 | } 149 | } 150 | if (fail == 1) 151 | xputs("BAD!\n"); 152 | else 153 | xputs("OK!\n"); 154 | 155 | 156 | xprintf("knuth_yao_asm:"); 157 | fail=0; 158 | for (i=0; iQBY4) && (small_c1[j]QBY4) && (small_c1[j]
© COPYRIGHT 2013 STMicroelectronics
95 | * 96 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 97 | * You may not use this file except in compliance with the License. 98 | * You may obtain a copy of the License at: 99 | * 100 | * http://www.st.com/software_license_agreement_liberty_v2 101 | * 102 | * Unless required by applicable law or agreed to in writing, software 103 | * distributed under the License is distributed on an "AS IS" BASIS, 104 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 105 | * See the License for the specific language governing permissions and 106 | * limitations under the License. 107 | * 108 | ****************************************************************************** 109 | */ 110 | 111 | /** @addtogroup CMSIS 112 | * @{ 113 | */ 114 | 115 | /** @addtogroup stm32f4xx_system 116 | * @{ 117 | */ 118 | 119 | /** @addtogroup STM32F4xx_System_Private_Includes 120 | * @{ 121 | */ 122 | 123 | #include "stm32f4xx.h" 124 | 125 | /** 126 | * @} 127 | */ 128 | 129 | /** @addtogroup STM32F4xx_System_Private_TypesDefinitions 130 | * @{ 131 | */ 132 | 133 | /** 134 | * @} 135 | */ 136 | 137 | /** @addtogroup STM32F4xx_System_Private_Defines 138 | * @{ 139 | */ 140 | 141 | /************************* Miscellaneous Configuration ************************/ 142 | /*!< Uncomment the following line if you need to use external SRAM or SDRAM mounted 143 | on STM324xG_EVAL/STM324x7I_EVAL boards as data memory */ 144 | /* #define DATA_IN_ExtSRAM */ 145 | 146 | /*!< Uncomment the following line if you need to relocate your vector Table in 147 | Internal SRAM. */ 148 | /* #define VECT_TAB_SRAM */ 149 | #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. 150 | This value must be a multiple of 0x200. */ 151 | /******************************************************************************/ 152 | 153 | /************************* PLL Parameters *************************************/ 154 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ 155 | #define PLL_M 25 156 | 157 | #define PLL_N 336 158 | 159 | /* SYSCLK = PLL_VCO / PLL_P */ 160 | #define PLL_P 2 161 | 162 | /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ 163 | #define PLL_Q 7 164 | 165 | /******************************************************************************/ 166 | 167 | /** 168 | * @} 169 | */ 170 | 171 | /** @addtogroup STM32F4xx_System_Private_Macros 172 | * @{ 173 | */ 174 | 175 | /** 176 | * @} 177 | */ 178 | 179 | /** @addtogroup STM32F4xx_System_Private_Variables 180 | * @{ 181 | */ 182 | 183 | uint32_t SystemCoreClock = 168000000; 184 | 185 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 186 | 187 | /** 188 | * @} 189 | */ 190 | 191 | /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes 192 | * @{ 193 | */ 194 | 195 | static void SetSysClock(void); 196 | #if defined (DATA_IN_ExtSRAM) 197 | static void SystemInit_ExtMemCtl(void); 198 | #endif /* DATA_IN_ExtSRAM */ 199 | 200 | /** 201 | * @} 202 | */ 203 | 204 | /** @addtogroup STM32F4xx_System_Private_Functions 205 | * @{ 206 | */ 207 | 208 | /** 209 | * @brief Setup the microcontroller system 210 | * Initialize the Embedded Flash Interface, the PLL and update the 211 | * SystemFrequency variable. 212 | * @param None 213 | * @retval None 214 | */ 215 | void SystemInit(void) 216 | { 217 | /* FPU settings ------------------------------------------------------------*/ 218 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 219 | SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ 220 | #endif 221 | /* Reset the RCC clock configuration to the default reset state ------------*/ 222 | /* Set HSION bit */ 223 | RCC->CR |= (uint32_t)0x00000001; 224 | 225 | /* Reset CFGR register */ 226 | RCC->CFGR = 0x00000000; 227 | 228 | /* Reset HSEON, CSSON and PLLON bits */ 229 | RCC->CR &= (uint32_t)0xFEF6FFFF; 230 | 231 | /* Reset PLLCFGR register */ 232 | RCC->PLLCFGR = 0x24003010; 233 | 234 | /* Reset HSEBYP bit */ 235 | RCC->CR &= (uint32_t)0xFFFBFFFF; 236 | 237 | /* Disable all interrupts */ 238 | RCC->CIR = 0x00000000; 239 | 240 | #if defined (DATA_IN_ExtSRAM) 241 | SystemInit_ExtMemCtl(); 242 | #endif /* DATA_IN_ExtSRAM */ 243 | 244 | /* Configure the System clock source, PLL Multiplier and Divider factors, 245 | AHB/APBx prescalers and Flash settings ----------------------------------*/ 246 | SetSysClock(); 247 | 248 | /* Configure the Vector Table location add offset address ------------------*/ 249 | #ifdef VECT_TAB_SRAM 250 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ 251 | #else 252 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ 253 | #endif 254 | } 255 | 256 | /** 257 | * @brief Update SystemCoreClock variable according to Clock Register Values. 258 | * The SystemCoreClock variable contains the core clock (HCLK), it can 259 | * be used by the user application to setup the SysTick timer or configure 260 | * other parameters. 261 | * 262 | * @note Each time the core clock (HCLK) changes, this function must be called 263 | * to update SystemCoreClock variable value. Otherwise, any configuration 264 | * based on this variable will be incorrect. 265 | * 266 | * @note - The system frequency computed by this function is not the real 267 | * frequency in the chip. It is calculated based on the predefined 268 | * constant and the selected clock source: 269 | * 270 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 271 | * 272 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 273 | * 274 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 275 | * or HSI_VALUE(*) multiplied/divided by the PLL factors. 276 | * 277 | * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value 278 | * 16 MHz) but the real value may vary depending on the variations 279 | * in voltage and temperature. 280 | * 281 | * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value 282 | * 25 MHz), user has to ensure that HSE_VALUE is same as the real 283 | * frequency of the crystal used. Otherwise, this function may 284 | * have wrong result. 285 | * 286 | * - The result of this function could be not correct when using fractional 287 | * value for HSE crystal. 288 | * 289 | * @param None 290 | * @retval None 291 | */ 292 | void SystemCoreClockUpdate(void) 293 | { 294 | uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; 295 | 296 | /* Get SYSCLK source -------------------------------------------------------*/ 297 | tmp = RCC->CFGR & RCC_CFGR_SWS; 298 | 299 | switch (tmp) 300 | { 301 | case 0x00: /* HSI used as system clock source */ 302 | SystemCoreClock = HSI_VALUE; 303 | break; 304 | case 0x04: /* HSE used as system clock source */ 305 | SystemCoreClock = HSE_VALUE; 306 | break; 307 | case 0x08: /* PLL used as system clock source */ 308 | 309 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N 310 | SYSCLK = PLL_VCO / PLL_P 311 | */ 312 | pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; 313 | pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; 314 | 315 | if (pllsource != 0) 316 | { 317 | /* HSE used as PLL clock source */ 318 | pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); 319 | } 320 | else 321 | { 322 | /* HSI used as PLL clock source */ 323 | pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); 324 | } 325 | 326 | pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; 327 | SystemCoreClock = pllvco/pllp; 328 | break; 329 | default: 330 | SystemCoreClock = HSI_VALUE; 331 | break; 332 | } 333 | /* Compute HCLK frequency --------------------------------------------------*/ 334 | /* Get HCLK prescaler */ 335 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 336 | /* HCLK frequency */ 337 | SystemCoreClock >>= tmp; 338 | } 339 | 340 | /** 341 | * @brief Configures the System clock source, PLL Multiplier and Divider factors, 342 | * AHB/APBx prescalers and Flash settings 343 | * @Note This function should be called only once the RCC clock configuration 344 | * is reset to the default reset state (done in SystemInit() function). 345 | * @param None 346 | * @retval None 347 | */ 348 | static void SetSysClock(void) 349 | { 350 | /******************************************************************************/ 351 | /* PLL (clocked by HSE) used as System clock source */ 352 | /******************************************************************************/ 353 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 354 | 355 | /* Enable HSE */ 356 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 357 | 358 | /* Wait till HSE is ready and if Time out is reached exit */ 359 | do 360 | { 361 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 362 | StartUpCounter++; 363 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 364 | 365 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 366 | { 367 | HSEStatus = (uint32_t)0x01; 368 | } 369 | else 370 | { 371 | HSEStatus = (uint32_t)0x00; 372 | } 373 | 374 | if (HSEStatus == (uint32_t)0x01) 375 | { 376 | /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ 377 | RCC->APB1ENR |= RCC_APB1ENR_PWREN; 378 | PWR->CR |= PWR_CR_VOS; 379 | 380 | /* HCLK = SYSCLK / 1*/ 381 | RCC->CFGR |= RCC_CFGR_HPRE_DIV1; 382 | 383 | /* PCLK2 = HCLK / 2*/ 384 | RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; 385 | 386 | /* PCLK1 = HCLK / 4*/ 387 | RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; 388 | 389 | /* Configure the main PLL */ 390 | RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | 391 | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); 392 | 393 | /* Enable the main PLL */ 394 | RCC->CR |= RCC_CR_PLLON; 395 | 396 | /* Wait till the main PLL is ready */ 397 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 398 | { 399 | } 400 | 401 | /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ 402 | FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; 403 | 404 | /* Select the main PLL as system clock source */ 405 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 406 | RCC->CFGR |= RCC_CFGR_SW_PLL; 407 | 408 | /* Wait till the main PLL is used as system clock source */ 409 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); 410 | { 411 | } 412 | } 413 | else 414 | { /* If HSE fails to start-up, the application will have wrong clock 415 | configuration. User can add here some code to deal with this error */ 416 | } 417 | 418 | } 419 | 420 | /** 421 | * @brief Setup the external memory controller. Called in startup_stm32f4xx.s 422 | * before jump to __main 423 | * @param None 424 | * @retval None 425 | */ 426 | #ifdef DATA_IN_ExtSRAM 427 | /** 428 | * @brief Setup the external memory controller. 429 | * Called in startup_stm32f4xx.s before jump to main. 430 | * This function configures the external SRAM mounted on STM324xG_EVAL/STM324x7I boards 431 | * This SRAM will be used as program data memory (including heap and stack). 432 | * @param None 433 | * @retval None 434 | */ 435 | void SystemInit_ExtMemCtl(void) 436 | { 437 | /*-- GPIOs Configuration -----------------------------------------------------*/ 438 | /* 439 | +-------------------+--------------------+------------------+------------------+ 440 | + SRAM pins assignment + 441 | +-------------------+--------------------+------------------+------------------+ 442 | | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | 443 | | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | 444 | | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | 445 | | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | 446 | | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | 447 | | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | 448 | | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | 449 | | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |-----------------+ 450 | | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 | 451 | | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 | 452 | | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |-----------------+ 453 | | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 | 454 | | | PE15 <-> FSMC_D12 | 455 | +------------------+------------------+ 456 | */ 457 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ 458 | RCC->AHB1ENR = 0x00000078; 459 | 460 | /* Connect PDx pins to FSMC Alternate function */ 461 | GPIOD->AFR[0] = 0x00CCC0CC; 462 | GPIOD->AFR[1] = 0xCCCCCCCC; 463 | /* Configure PDx pins in Alternate function mode */ 464 | GPIOD->MODER = 0xAAAA0A8A; 465 | /* Configure PDx pins speed to 100 MHz */ 466 | GPIOD->OSPEEDR = 0xFFFF0FCF; 467 | /* Configure PDx pins Output type to push-pull */ 468 | GPIOD->OTYPER = 0x00000000; 469 | /* No pull-up, pull-down for PDx pins */ 470 | GPIOD->PUPDR = 0x00000000; 471 | 472 | /* Connect PEx pins to FSMC Alternate function */ 473 | GPIOE->AFR[0] = 0xC00CC0CC; 474 | GPIOE->AFR[1] = 0xCCCCCCCC; 475 | /* Configure PEx pins in Alternate function mode */ 476 | GPIOE->MODER = 0xAAAA828A; 477 | /* Configure PEx pins speed to 100 MHz */ 478 | GPIOE->OSPEEDR = 0xFFFFC3CF; 479 | /* Configure PEx pins Output type to push-pull */ 480 | GPIOE->OTYPER = 0x00000000; 481 | /* No pull-up, pull-down for PEx pins */ 482 | GPIOE->PUPDR = 0x00000000; 483 | 484 | /* Connect PFx pins to FSMC Alternate function */ 485 | GPIOF->AFR[0] = 0x00CCCCCC; 486 | GPIOF->AFR[1] = 0xCCCC0000; 487 | /* Configure PFx pins in Alternate function mode */ 488 | GPIOF->MODER = 0xAA000AAA; 489 | /* Configure PFx pins speed to 100 MHz */ 490 | GPIOF->OSPEEDR = 0xFF000FFF; 491 | /* Configure PFx pins Output type to push-pull */ 492 | GPIOF->OTYPER = 0x00000000; 493 | /* No pull-up, pull-down for PFx pins */ 494 | GPIOF->PUPDR = 0x00000000; 495 | 496 | /* Connect PGx pins to FSMC Alternate function */ 497 | GPIOG->AFR[0] = 0x00CCCCCC; 498 | GPIOG->AFR[1] = 0x000000C0; 499 | /* Configure PGx pins in Alternate function mode */ 500 | GPIOG->MODER = 0x00080AAA; 501 | /* Configure PGx pins speed to 100 MHz */ 502 | GPIOG->OSPEEDR = 0x000C0FFF; 503 | /* Configure PGx pins Output type to push-pull */ 504 | GPIOG->OTYPER = 0x00000000; 505 | /* No pull-up, pull-down for PGx pins */ 506 | GPIOG->PUPDR = 0x00000000; 507 | 508 | /*-- FSMC Configuration ------------------------------------------------------*/ 509 | /* Enable the FSMC interface clock */ 510 | RCC->AHB3ENR = 0x00000001; 511 | 512 | /* Configure and enable Bank1_SRAM2 */ 513 | FSMC_Bank1->BTCR[2] = 0x00001011; 514 | FSMC_Bank1->BTCR[3] = 0x00110212; 515 | FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF; 516 | /* 517 | Bank1_SRAM2 is configured as follow: 518 | 519 | NORSRAMTimingStructure.FSMC_AddressSetupTime = 2; 520 | NORSRAMTimingStructure.FSMC_AddressHoldTime = 1; 521 | NORSRAMTimingStructure.FSMC_DataSetupTime = 2; 522 | NORSRAMTimingStructure.FSMC_BusTurnAroundDuration = 1; 523 | NORSRAMTimingStructure.FSMC_CLKDivision = 2; 524 | NORSRAMTimingStructure.FSMC_DataLatency = 2; 525 | NORSRAMTimingStructure.FSMC_AccessMode = FSMC_AccessMode_A; 526 | 527 | FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; 528 | FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; 529 | FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; 530 | FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; 531 | FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; 532 | FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; 533 | FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; 534 | FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; 535 | FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; 536 | FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; 537 | FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; 538 | FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; 539 | FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; 540 | FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; 541 | FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &NORSRAMTimingStructure; 542 | */ 543 | 544 | } 545 | #endif /* DATA_IN_ExtSRAM */ 546 | 547 | /** 548 | * @} 549 | */ 550 | 551 | /** 552 | * @} 553 | */ 554 | 555 | /** 556 | * @} 557 | */ 558 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 559 | 560 | uint32_t getSystemCoreClock() 561 | { 562 | SystemCoreClockUpdate(); 563 | return SystemCoreClock; 564 | } 565 | -------------------------------------------------------------------------------- /x86/lwe.c: -------------------------------------------------------------------------------- 1 | #include "lwe.h" 2 | #include "luts.h" 3 | #include "stdlib.h" 4 | #include "global.h" 5 | #include 6 | #include 7 | 8 | #ifdef USE_FAKE_GET_RAND 9 | uint32_t g_fake_rand; 10 | #endif 11 | 12 | #ifdef USE_FAKE_GET_RAND 13 | uint32_t get_rand() { return g_fake_rand; } 14 | #else 15 | #ifdef USE_TRNG 16 | #define GET_TRNG_NUMBER (*(volatile unsigned int *) (RNG_ADDR+8)); 17 | uint32_t get_rand() 18 | { 19 | uint32_t rnd = GET_TRNG_NUMBER; 20 | rnd |= 0x80000000; // set the least significant bit 21 | return rnd; 22 | } 23 | 24 | uint32_t get_rand_basic() 25 | { 26 | return GET_TRNG_NUMBER; 27 | } 28 | #else 29 | uint32_t get_rand() 30 | { 31 | uint32_t rnd = rand(); 32 | rnd |= 0x80000000; // set the least significant bit 33 | return rnd; 34 | } 35 | 36 | uint32_t get_rand_basic() 37 | { 38 | return rand(); 39 | } 40 | 41 | #endif 42 | #endif 43 | 44 | uint32_t clz(uint32_t a) { 45 | int i; 46 | for (i = 0; i < 32; i++) { 47 | if ((a >> (31 - i)) == 1) { 48 | return i; 49 | } 50 | } 51 | return 32; 52 | } 53 | 54 | /* 55 | * this function does *not* require -q= 0 ? (a % MODULUS) : (a % MODULUS) + MODULUS; 62 | while (ret2 < 0) { 63 | ret2 += MODULUS; 64 | } 65 | while (ret2 > MODULUS) { 66 | ret2 -= MODULUS; 67 | } 68 | #ifdef DEBUG_PRINTF 69 | if (!(ret2 >= 0 && ret2 < MODULUS)) { 70 | printf("error: %d\n", ret2); 71 | } 72 | #endif 73 | assert(ret2 >= 0 && ret2 < MODULUS); 74 | return (uint32_t) ret2; 75 | } 76 | 77 | void knuth_yao2(uint16_t a[M]) { 78 | int i; 79 | uint32_t rnd; 80 | int sample_in_table; 81 | rnd = get_rand(); 82 | for (i = 0; i < M / 2; i++) { 83 | #ifdef DISABLE_KNUTH_YAO 84 | a[2 * i + 1] = 0; 85 | a[2 * i] = 0; 86 | #else 87 | a[2 * i] = knuth_yao_single_number(&rnd,&sample_in_table); 88 | a[2 * i+1] = knuth_yao_single_number(&rnd,&sample_in_table); 89 | #endif 90 | } 91 | } 92 | 93 | void knuth_yao_shuffled(uint16_t result[M]) 94 | { 95 | int i, sample_in_table; 96 | uint16_t sample; 97 | uint32_t rnd; 98 | int counter1=0; 99 | int counter2=0; 100 | rnd = get_rand(); 101 | for (i = 0; i < M / 2; i++) { 102 | #ifdef DISABLE_KNUTH_YAO 103 | result[2 * i + 1] = 0; 104 | result[2 * i] = 0; 105 | #else 106 | sample_in_table=0xff; 107 | sample = knuth_yao_single_number(&rnd,&sample_in_table); 108 | //result[2 * i] = sample; 109 | 110 | if (sample_in_table==1) { 111 | result[counter1]=sample; 112 | counter1++; 113 | } 114 | else 115 | { 116 | result[M-counter2-1]=sample; 117 | counter2++; 118 | } 119 | 120 | sample = knuth_yao_single_number(&rnd,&sample_in_table); 121 | // result[2 * i+1] = sample; 122 | 123 | if (sample_in_table==1) { 124 | result[counter1]=sample; 125 | counter1++; 126 | } 127 | else 128 | { 129 | result[M-counter2-1]=sample; 130 | counter2++; 131 | } 132 | 133 | #endif 134 | } 135 | 136 | 137 | while (counter2>0) { 138 | uint32_t rnd = get_rand()&(M-1);//Random number with mask 139 | if (rnd<(M-counter2)) 140 | { 141 | //Swap 142 | sample=result[rnd]; 143 | result[rnd]=result[M-counter2]; 144 | result[M-counter2]=sample; 145 | counter2--; 146 | } 147 | } 148 | } 149 | 150 | //#define NEW_RND_BOTTOM 0 151 | 152 | #define NEW_RND_BOTTOM 1 153 | #define NEW_RND_LARGE 32 - 9 154 | #define NEW_RND_MID 32 - 6 155 | 156 | void knuth_yao_small(uint16_t a[M]) 157 | { 158 | int i; 159 | uint32_t rnd; 160 | uint32_t sample_in_table; 161 | rnd = get_rand(); 162 | for (i = 0; i < M / 2; i++) { 163 | #ifdef DISABLE_KNUTH_YAO 164 | a[2 * i + 1] = 0; 165 | a[2 * i] = 0; 166 | #else 167 | a[2 * i + 1] = knuth_yao_single_number(&rnd,&sample_in_table); 168 | a[2 * i] = knuth_yao_single_number(&rnd,&sample_in_table); 169 | #endif 170 | } 171 | } 172 | 173 | void knuth_yao_smaller_tables2(uint16_t *a) { 174 | int i; 175 | uint32_t rnd; 176 | rnd = get_rand(); 177 | for (i = 0; i < M / 2; i++) { 178 | #ifdef DISABLE_KNUTH_YAO 179 | a[2 * i + 1] = 0; 180 | a[2 * i] = 0; 181 | #else 182 | a[2 * i + 1] = knuth_yao_smaller_tables_single_number(&rnd); 183 | a[2 * i] = knuth_yao_smaller_tables_single_number(&rnd); 184 | 185 | #endif 186 | } 187 | } 188 | 189 | uint32_t knuth_yao_smaller_tables_single_number(uint32_t *rnd) { 190 | int distance, row, column, index, sample, sample_msb; 191 | 192 | unsigned int high, low; 193 | #ifdef DEBUG_PRINTF 194 | printf("Start rnd:%d\n", *rnd); 195 | #endif 196 | index = (*rnd) & 0xff; 197 | (*rnd) = (*rnd) >> 8; 198 | sample = lut1[index]; // M elements in lut1 199 | sample_msb = sample & 16; 200 | if (sample_msb == 0) // lookup was successful 201 | { 202 | if ((*rnd) == NEW_RND_BOTTOM) { 203 | (*rnd) = get_rand(); 204 | } 205 | sample = sample & 0xf; 206 | if ((*rnd) & 1) 207 | sample = (MODULUS - sample); // 9th bit in (*rnd) is the sign 208 | (*rnd) = (*rnd) >> 1; 209 | // We know that in the next call we will need 8 bits! 210 | if (clz(*rnd) > (NEW_RND_LARGE)) { 211 | (*rnd) = get_rand(); 212 | } 213 | 214 | return sample; 215 | } else { 216 | if (clz(*rnd) > (NEW_RND_MID)) { 217 | (*rnd) = get_rand(); 218 | } 219 | distance = sample & KN_DISTANCE1_MASK; 220 | index = ((*rnd) & 0x1f) + 32 * distance; 221 | (*rnd) = (*rnd) >> 5; 222 | if ((*rnd) == NEW_RND_BOTTOM) { 223 | (*rnd) = get_rand(); 224 | } 225 | sample = lut2[index]; // 224 elements in lut2 226 | sample_msb = sample & 32; 227 | if (sample_msb == 0) // lookup was successful 228 | { 229 | sample = sample & 31; 230 | if ((*rnd) & 1) 231 | sample = (MODULUS - sample); // 9th bit in rnd is the sign 232 | (*rnd) = (*rnd) >> 1; 233 | if (clz(*rnd) > (NEW_RND_LARGE)) { 234 | (*rnd) = get_rand(); 235 | } 236 | return sample; 237 | } else { 238 | // Real knuth-yao 239 | distance = sample & KN_DISTANCE2_MASK; 240 | 241 | // NB: Need to update PMAT_MAX_COL! 242 | for (column = 0; column < PMAT_MAX_COL; column++) { 243 | distance = distance * 2 + ((*rnd) & 1); 244 | (*rnd) = (*rnd) >> 1; 245 | if ((*rnd) == NEW_RND_BOTTOM) { 246 | (*rnd) = get_rand(); 247 | } 248 | #ifdef DEBUG_PRINTF 249 | printf("rnd:%d, dist:%d, col:%d\n", ((*rnd)), distance, column + 13); 250 | #endif 251 | low = pmat_cols_small_low2[column]; 252 | 253 | // if ((int)((unsigned int)distance - 254 | // pmat_cols_small_hamming[column])<0) 255 | { 256 | // Assume that HAMMING_TABLE_SIZE<7 and therefore column<7 257 | // pmat_cols_small_high only contains a value when column=8 (Real 258 | // column 20) 259 | 260 | // This means that it must be inside the high part 261 | // for(row=(54-32); row>=0; row--) 262 | for (row = (31); row >= 0; row--) { 263 | distance = 264 | distance - (low >> 31); // subtract the most significant bit 265 | low = low << 1; 266 | if (distance == -1) { 267 | if ((*rnd) & 1) 268 | sample = (MODULUS - row); 269 | else 270 | sample = row; 271 | (*rnd) = (*rnd) >> 1; 272 | if (clz(*rnd) > (NEW_RND_LARGE)) { 273 | (*rnd) = get_rand(); 274 | } 275 | return sample; 276 | } 277 | } 278 | } 279 | } 280 | for (column = HAMMING_TABLE_SIZE; (column < (109 - 13)); column++) { 281 | high = pmat_cols_small_high2[column]; 282 | low = pmat_cols_small_low2[column]; 283 | 284 | distance = distance * 2 + ((*rnd) & 1); 285 | (*rnd) = (*rnd) >> 1; 286 | // if ((column==32)||(column==64)||(column==96)) 287 | if ((*rnd) == NEW_RND_BOTTOM) { 288 | (*rnd) = rand(); 289 | } 290 | #ifdef DEBUG_PRINTF 291 | printf("rnd:%d, dist:%d, col:%d\n", ((*rnd)), distance, column); 292 | #endif 293 | 294 | for (row = 54; row >= 32; row--) { 295 | distance = 296 | distance - (high >> 31); // subtract the most significant bit 297 | high = high << 1; 298 | 299 | if (distance == -1) { 300 | if ((*rnd) & 1) 301 | sample = (MODULUS - row); 302 | else 303 | sample = row; 304 | (*rnd) = (*rnd) >> 1; 305 | if (clz(*rnd) > (NEW_RND_LARGE)) { 306 | (*rnd) = rand(); 307 | } 308 | return sample; 309 | } 310 | } 311 | // for(row=(54-32); row>=0; row--) 312 | for (row = (31); row >= 0; row--) { 313 | distance = distance - (low >> 31); // subtract the most significant 314 | // bit 315 | low = low << 1; 316 | if (distance == -1) { 317 | if ((*rnd) & 1) 318 | sample = (MODULUS - row); 319 | else 320 | sample = row; 321 | (*rnd) = (*rnd) >> 1; 322 | if (clz(*rnd) > (NEW_RND_LARGE)) { 323 | (*rnd) = rand(); 324 | } 325 | return sample; 326 | } 327 | } 328 | } 329 | } 330 | } 331 | return -1; 332 | } 333 | 334 | uint32_t knuth_yao_single_number(uint32_t *rnd, int * sample_in_table) 335 | { 336 | int distance; 337 | int row, column; 338 | 339 | uint32_t index, sample, sample_msb; 340 | 341 | #ifdef DEBUG_PRINTF 342 | printf("Start rnd:%x\n", *rnd); 343 | #endif 344 | index = (*rnd) & 0xff; 345 | (*rnd) = (*rnd) >> 8; 346 | 347 | sample = lut1[index]; // M elements in lut1 348 | sample_msb = sample & 16; 349 | if (sample_msb == 0) // lookup was successful 350 | { 351 | if ((*rnd) == NEW_RND_BOTTOM) { 352 | (*rnd) = get_rand(); 353 | } 354 | sample = sample & 0xf; 355 | if ((*rnd) & 1) 356 | sample = (MODULUS - sample); // 9th bit in rnd is the sign 357 | (*rnd) = (*rnd) >> 1; 358 | // We know that in the next call we will need 8 bits! 359 | if (clz(*rnd) > (NEW_RND_LARGE)) { 360 | (*rnd) = get_rand(); 361 | } 362 | #ifdef DEBUG_PRINTF 363 | printf("lut1:%x\n", sample); 364 | #endif 365 | *sample_in_table=1; 366 | return sample; 367 | } else { 368 | if (clz(*rnd) > (NEW_RND_MID)) { 369 | (*rnd) = get_rand(); 370 | } 371 | distance = sample & KN_DISTANCE1_MASK; 372 | index = ((*rnd) & 0x1f) + 32 * distance; 373 | (*rnd) = (*rnd) >> 5; 374 | if ((*rnd) == NEW_RND_BOTTOM) { 375 | (*rnd) = get_rand(); 376 | } 377 | sample = lut2[index]; // 224 elements in lut2 378 | sample_msb = sample & 32; 379 | if (sample_msb == 0) // lookup was successful 380 | { 381 | sample = sample & 31; 382 | if ((*rnd) & 1) 383 | sample = (MODULUS - sample); // 9th bit in rnd is the sign 384 | (*rnd) = (*rnd) >> 1; 385 | if (clz(*rnd) > (NEW_RND_LARGE)) { 386 | (*rnd) = get_rand(); 387 | } 388 | #ifdef DEBUG_PRINTF 389 | printf("lut2:%x\n", sample); 390 | #endif 391 | *sample_in_table=1; 392 | return sample; 393 | } else { 394 | // Real knuth-yao bitscanning 395 | distance = sample & KN_DISTANCE2_MASK; 396 | for (column = 13; (column < PMAT_MAX_COL); column++) { 397 | distance = distance * 2 + ((*rnd) & 1); 398 | (*rnd) = (*rnd) >> 1; 399 | if ((*rnd) == NEW_RND_BOTTOM) { 400 | (*rnd) = get_rand(); 401 | } 402 | #ifdef DEBUG_PRINTF 403 | printf("rnd:%x, dist:%d, col:%d\n", (*rnd), distance, column); 404 | #endif 405 | 406 | // Read probability-column 0 and count the number of non-zeros 407 | for (row = 54; row >= 0; row--) { 408 | distance = distance - pmat[row][column]; 409 | if (distance < 0) { 410 | #ifdef DEBUG_PRINTF 411 | printf("rnd:%d", (*rnd)); 412 | #endif 413 | if ((*rnd) & 1) 414 | sample = (MODULUS - row); 415 | else 416 | sample = row; 417 | (*rnd) = (*rnd) >> 1; 418 | if (clz(*rnd) > (NEW_RND_LARGE)) { 419 | (*rnd) = get_rand(); 420 | } 421 | 422 | *sample_in_table=0; 423 | return sample; 424 | } 425 | } 426 | // rnd = rnd >> 1; 427 | } 428 | } 429 | } 430 | 431 | *sample_in_table=0; 432 | return 0xffffffff; 433 | } 434 | 435 | void a_gen2(uint16_t a[]) { 436 | uint32_t i, r; 437 | 438 | for (i = 0; i < M / 2; i++) { 439 | r = (uint32_t)rand(); 440 | a[2 * i] = mod(r & 0xffff); 441 | a[2 * i + 1] = mod((r >> 16)); 442 | } 443 | 444 | fwd_ntt2(a); 445 | } 446 | 447 | void r1_gen2(uint16_t r1[]) { 448 | 449 | #ifdef USE_KNUTH_YAO_SHUFFLE 450 | knuth_yao_shuffled(r1); 451 | #else 452 | knuth_yao2(r1); 453 | #endif 454 | 455 | fwd_ntt2(r1); 456 | } 457 | 458 | void r2_gen2(uint16_t r2[M]) { 459 | uint16_t i, j, r, bit, sign; 460 | 461 | for (i = 0; i < M;) { 462 | r = (uint16_t) rand(); // NB: Need to ensure that this is a good source of entropy 463 | 464 | for (j = 0; j < 16; j++) { 465 | bit = r & 1; 466 | sign = (r >> 1) & 1; 467 | if (sign == 1 && bit == 1) 468 | bit = (MODULUS - 1); 469 | r2[i++] = bit; 470 | r = r >> 2; 471 | } 472 | } 473 | fwd_ntt2(r2); 474 | } 475 | 476 | void rearrange2(uint16_t a[M]) { 477 | uint32_t i; 478 | uint32_t bit1, bit2, bit3, bit4, bit5, bit6, bit7; 479 | uint32_t swp_index; 480 | 481 | uint16_t u1, u2; 482 | 483 | for (i = 1; i < M / 2; i++) { 484 | bit1 = i % 2; 485 | bit2 = (i >> 1) % 2; 486 | bit3 = (i >> 2) % 2; 487 | bit4 = (i >> 3) % 2; 488 | bit5 = (i >> 4) % 2; 489 | bit6 = (i >> 5) % 2; 490 | bit7 = (i >> 6) % 2; 491 | 492 | #ifdef NTT512 493 | int bit8 = (i >> 7) % 2; 494 | swp_index = bit1 * 128 + bit2 * 64 + bit3 * 32 + bit4 * 16 + bit5 * 8 + 495 | bit6 * 4 + bit7 * 2 + bit8; 496 | #else 497 | swp_index = bit1 * 64 + bit2 * 32 + bit3 * 16 + bit4 * 8 + bit5 * 4 + 498 | bit6 * 2 + bit7; 499 | #endif 500 | 501 | if (swp_index > i) { 502 | u1 = a[2 * i]; 503 | u2 = a[2 * i + 1]; 504 | 505 | a[2 * i] = a[2 * swp_index]; 506 | a[2 * i + 1] = a[2 * swp_index + 1]; 507 | 508 | a[2 * swp_index] = u1; 509 | a[2 * swp_index + 1] = u2; 510 | } 511 | } 512 | } 513 | 514 | bool compare_vectors(uint16_t *a, uint16_t *b) 515 | { 516 | int i; 517 | for (i = 0; i < M; i++) { 518 | if (a[i] != b[i]) 519 | return false; 520 | } 521 | return true; 522 | ; 523 | } 524 | 525 | void bitreverse2(uint16_t a[M]) { 526 | uint32_t i, swp_index; 527 | uint32_t bit1, bit2, bit3, bit4, bit5, bit6, bit7, bit8; 528 | uint32_t q1, r1, q2, r2; 529 | uint16_t temp = 0; 530 | 531 | for (i = 0; i < M; i++) { 532 | bit1 = i % 2; 533 | bit2 = (i >> 1) % 2; 534 | bit3 = (i >> 2) % 2; 535 | bit4 = (i >> 3) % 2; 536 | bit5 = (i >> 4) % 2; 537 | bit6 = (i >> 5) % 2; 538 | bit7 = (i >> 6) % 2; 539 | bit8 = (i >> 7) % 2; 540 | 541 | #ifdef NTT512 542 | int bit9 = (i >> 8) % 2; 543 | swp_index = bit1 * 256 + bit2 * 128 + bit3 * 64 + bit4 * 32 + bit5 * 16 + 544 | bit6 * 8 + bit7 * 4 + bit8 * 2 + bit9; 545 | #else 546 | swp_index = bit1 * 128 + bit2 * 64 + bit3 * 32 + bit4 * 16 + bit5 * 8 + 547 | bit6 * 4 + bit7 * 2 + bit8; 548 | #endif 549 | q1 = i / 2; 550 | r1 = i % 2; 551 | q2 = swp_index / 2; 552 | r2 = swp_index % 2; 553 | 554 | if (swp_index > i) { 555 | if (r2 == 0) 556 | temp = a[2 * q2]; 557 | if (r2 == 1) 558 | temp = a[2 * q2 + 1]; 559 | if (r2 == 0 && r1 == 0) 560 | a[2 * q2] = a[2 * q1]; 561 | if (r2 == 0 && r1 == 1) 562 | a[2 * q2] = a[2 * q1 + 1]; 563 | if (r2 == 1 && r1 == 0) 564 | a[2 * q2 + 1] = a[2 * q1]; 565 | if (r2 == 1 && r1 == 1) 566 | a[2 * q2 + 1] = a[2 * q1 + 1]; 567 | if (r1 == 0) 568 | a[2 * q1] = temp; 569 | if (r1 == 1) 570 | a[2 * q1 + 1] = temp; 571 | } 572 | } 573 | } 574 | 575 | void fwd_ntt2(uint16_t a[]) { 576 | int i, j, k, m; 577 | uint32_t u1, t1, u2, t2; 578 | uint32_t primrt, omega; 579 | 580 | i = 0; 581 | for (m = 2; m <= M / 2; m = 2 * m) { 582 | primrt = primrt_omega_table[i]; 583 | omega = primrt_omega_table[i + 1]; 584 | i++; 585 | 586 | for (j = 0; j < m; j += 2) { 587 | for (k = 0; k < M; k = k + 2 * m) { 588 | u1 = a[j + k]; 589 | t1 = mod(omega * a[j + k + 1]); 590 | 591 | u2 = a[j + k + m]; 592 | t2 = mod(omega * a[j + k + m + 1]); 593 | 594 | a[j + k] = mod(u1 + t1); 595 | a[j + k + 1] = mod(u2 + t2); 596 | 597 | a[j + k + m] = mod(u1 - t1); 598 | a[j + k + m + 1] = mod(u2 - t2); 599 | 600 | } 601 | omega = omega * primrt; 602 | omega = mod(omega); 603 | } 604 | } 605 | 606 | primrt = FWD_CONST1; // mpz_set_str(primrt,"5118",10); 607 | omega = FWD_CONST2; // mpz_set_str(omega,"1065",10); 608 | for (j = 0; j < M / 2; j++) { 609 | t1 = omega * a[2 * j + 1]; 610 | t1 = mod(t1); 611 | u1 = a[2 * j]; 612 | a[2 * j] = mod(u1 + t1); 613 | a[2 * j + 1] = mod(u1 - t1); 614 | 615 | omega = omega * primrt; 616 | omega = mod(omega); 617 | } 618 | } 619 | 620 | 621 | 622 | void inv_ntt2(uint16_t a[M]) { 623 | int j, k, m; 624 | uint32_t u1, t1, u2, t2; 625 | uint32_t primrt, omega; 626 | primrt = 0; 627 | 628 | for (m = 2; m <= M / 2; m = 2 * m) { 629 | #ifdef NTT512 630 | switch (m) { 631 | case 2: 632 | primrt = 12288; 633 | break; 634 | case 4: 635 | primrt = 10810; 636 | break; 637 | case 8: 638 | primrt = 7143; 639 | break; 640 | case 16: 641 | primrt = 10984; 642 | break; 643 | case 32: 644 | primrt = 3542; 645 | break; 646 | case 64: 647 | primrt = 4821; 648 | break; 649 | case 128: 650 | primrt = 1170; 651 | break; 652 | case 256: 653 | primrt = 5755; 654 | break; 655 | } 656 | #else 657 | switch (m) { 658 | case 2: 659 | primrt = 7680; 660 | break; 661 | case 4: 662 | primrt = 3383; 663 | break; 664 | case 8: 665 | primrt = 5756; 666 | break; 667 | case 16: 668 | primrt = 1728; 669 | break; 670 | case 32: 671 | primrt = 7584; 672 | break; 673 | case 64: 674 | primrt = 6569; 675 | break; 676 | case 128: 677 | primrt = 6601; 678 | break; 679 | } 680 | #endif 681 | 682 | omega = 1; 683 | for (j = 0; j < m / 2; j++) { 684 | for (k = 0; k < M / 2; k = k + m) { 685 | t1 = omega * a[2 * (k + j) + 1]; 686 | t1 = mod(t1); 687 | u1 = a[2 * (k + j)]; 688 | t2 = omega * a[2 * (k + j + m / 2) + 1]; 689 | t2 = mod(t2); 690 | u2 = a[2 * (k + j + m / 2)]; 691 | 692 | a[2 * (k + j)] = mod(u1 + t1); 693 | a[2 * (k + j + m / 2)] = mod(u1 - t1); 694 | 695 | a[2 * (k + j) + 1] = mod(u2 + t2); 696 | a[2 * (k + j + m / 2) + 1] = mod(u2 - t2); 697 | } 698 | omega = omega * primrt; 699 | omega = mod(omega); 700 | } 701 | } 702 | 703 | primrt = INVCONST1; 704 | omega = 1; 705 | for (j = 0; j < M;) { 706 | u1 = a[j]; 707 | j++; 708 | t1 = omega * a[j]; 709 | t1 = mod(t1); 710 | 711 | a[j - 1] = mod(u1 + t1); 712 | a[j] = mod(u1 - t1); 713 | j++; 714 | 715 | omega = omega * primrt; 716 | omega = mod(omega); 717 | } 718 | uint32_t omega2 = INVCONST2; 719 | primrt = INVCONST3; 720 | omega = 1; 721 | 722 | for (j = 0; j < M;) { 723 | a[j] = mod(omega * a[j]); 724 | 725 | a[j] = mod(a[j] * SCALING); 726 | 727 | j++; 728 | a[j] = mod(omega2 * a[j]); 729 | 730 | a[j] = mod(a[j] * SCALING); 731 | j++; 732 | 733 | omega = omega * primrt; 734 | omega = mod(omega); 735 | omega2 = omega2 * primrt; 736 | omega2 = mod(omega2); 737 | } 738 | } 739 | 740 | uint32_t compare_simd(uint32_t a_0[M / 2], uint32_t a_1[M / 2], 741 | uint32_t large[M]) { 742 | int j; 743 | for (j = 0; j < M / 2; j++) { 744 | if (((large[j] & 0xffff) != a_0[j]) || ((large[j] >> 16) != a_1[j])) { 745 | return 0; 746 | } 747 | } 748 | 749 | return 1; 750 | } 751 | 752 | uint32_t compare_large_simd(uint32_t large_simd[M / 2], uint32_t large[M]) { 753 | int j; 754 | for (j = 0; j < M / 2; j++) { 755 | if (((large_simd[j] & 0xffff) != large[2 * j])) { 756 | return 0; 757 | } 758 | 759 | if ((large_simd[j] >> 16) != large[2 * j + 1]) { 760 | return 0; 761 | } 762 | } 763 | 764 | return 1; 765 | } 766 | 767 | void coefficient_mul2(uint16_t out[M], uint16_t b[], uint16_t c[]) { 768 | // a = b * c 769 | int j; 770 | 771 | for (j = 0; j < M; j++) { 772 | out[j] = mod((uint32_t)((uint32_t)b[j] * (uint32_t)c[j])); 773 | } 774 | } 775 | 776 | void coefficient_add2(uint16_t out[M], uint16_t b[M], uint16_t c[M]) 777 | { 778 | // a = b + c 779 | int j; 780 | 781 | for (j = 0; j < M; j++) { 782 | out[j] = mod((uint32_t)(b[j] + c[j])); 783 | } 784 | } 785 | 786 | void coefficient_mul_add2(uint16_t *result, uint16_t *large1, uint16_t *large2, uint16_t *large3) { 787 | // result=large1*large2+large3 788 | int j; 789 | uint32_t tmp; 790 | 791 | for (j = 0; j < M; j++) { 792 | tmp = large1[j] * large2[j]; 793 | result[j] = mod(tmp + (uint32_t)large3[j]); 794 | } 795 | } 796 | 797 | void coefficient_sub2(uint16_t result[M], uint16_t b[M], uint16_t c[M]) { 798 | int j; 799 | 800 | for (j = 0; j < M; j++) { 801 | result[j] = mod(b[j] - c[j]); 802 | } 803 | } 804 | 805 | void key_gen2(uint16_t a[M], uint16_t p[M], uint16_t r2[M]) { 806 | a_gen2(a); 807 | r1_gen2(p); 808 | r2_gen2(r2); 809 | 810 | uint16_t tmp_a[M]; 811 | 812 | // a = a*r2 813 | coefficient_mul2(tmp_a, a, r2); 814 | // p = p-a*r2 815 | coefficient_sub2(p, p, tmp_a); 816 | 817 | rearrange2(r2); 818 | } 819 | 820 | void RLWE_enc2(uint16_t a[M], uint16_t c1[M], uint16_t c2[M], uint16_t m[M], uint16_t p[M]) 821 | { 822 | int i; 823 | uint16_t e1[M], e2[M], e3[M]; 824 | uint16_t encoded_m[M]; 825 | for (i = 0; i < M; i++) { 826 | encoded_m[i] = m[i] * QBY2; // encoding of message 827 | } 828 | 829 | #ifdef USE_KNUTH_YAO_SHUFFLE 830 | knuth_yao_shuffled(e1); 831 | knuth_yao_shuffled(e2); 832 | knuth_yao_shuffled(e3); 833 | #else 834 | knuth_yao2(e1); 835 | knuth_yao2(e2); 836 | knuth_yao2(e3); 837 | #endif 838 | 839 | coefficient_add2(e3, e3, encoded_m); // e3 <-- e3 + m 840 | 841 | fwd_ntt2(e1); 842 | fwd_ntt2(e2); 843 | fwd_ntt2(e3); 844 | 845 | // m <-- a*e1 846 | coefficient_mul2(c1, a, e1); // c1 <-- a*e1 847 | coefficient_add2(c1, e2, c1); // c1 <-- e2 + a*e1(tmp_m); 848 | coefficient_mul2(c2, p, e1); // c2 <-- p*e1 849 | coefficient_add2(c2, e3, c2); // c2<-- e3 + p*e1 850 | 851 | rearrange2(c1); 852 | rearrange2(c2); 853 | } 854 | 855 | void RLWE_dec2(uint16_t c1[M], uint16_t c2[M], uint16_t r2[M]) 856 | { 857 | coefficient_mul2(c1, c1, r2); // c1 <-- c1*r2 858 | coefficient_add2(c1, c1, c2); // c1 <-- c1*r2 + c2 859 | 860 | inv_ntt2(c1); 861 | } 862 | 863 | void message_gen2(uint16_t m[M]) { 864 | int i; 865 | for (i = 0; i < M; i++) { 866 | m[i] = (uint16_t)(get_rand() % 2); 867 | } 868 | } 869 | 870 | void get_small_ntt_random_numbers(uint16_t *small1, uint16_t *small2, uint32_t i) 871 | { 872 | uint32_t j; 873 | uint32_t rnd1, rnd2; 874 | 875 | srand(i); 876 | for (j = 0; j < M / 2; j++) { 877 | rnd1 = get_rand() & 0x1FFF; 878 | rnd2 = get_rand() & 0x1FFF; 879 | small1[2*j] = mod(rnd1); 880 | small1[2*j+1] = mod(rnd2); 881 | small2[2 * j] = mod(rnd1); 882 | small2[2 * j + 1] = mod(rnd2); 883 | } 884 | } 885 | 886 | void get_ntt_random_numbers(uint32_t *large1, uint32_t *large2, uint32_t i) { 887 | uint32_t j; 888 | uint32_t rnd1, rnd2; 889 | 890 | srand(i); 891 | if (i == 0) { 892 | for (j = 0; j < M / 2; j++) { 893 | rnd1 = j + 1; 894 | rnd2 = j + 2; 895 | large1[j] = (rnd1 & 0xffff) + ((rnd2 & 0xffff) << 16); 896 | large2[2 * j] = rnd1; 897 | large2[2 * j + 1] = rnd2; 898 | } 899 | } else { 900 | for (j = 0; j < M / 2; j++) { 901 | rnd1 = get_rand() & 0x1FFF; 902 | rnd2 = get_rand() & 0x1FFF; 903 | large1[j] = (rnd1 & 0xffff) + ((rnd2 & 0xffff) << 16); 904 | large2[2 * j] = rnd1; 905 | large2[2 * j + 1] = rnd2; 906 | } 907 | } 908 | } 909 | 910 | void rearrange_for_final_test(uint16_t in[M], uint16_t out[M]) 911 | { 912 | int i; 913 | for (i = 0; i < M / 2; i += 2) { 914 | out[i] = in[2 * i]; 915 | out[i + 1] = in[2 * (i + 1)]; 916 | } 917 | 918 | for (i = 0; i < M / 2; i += 2) { 919 | out[i + M / 2] = in[2 * i + 1]; 920 | out[i + 1 + M / 2] = in[2 * (i + 1) + 1]; 921 | } 922 | } 923 | 924 | void get_rand_input(uint32_t i, uint32_t large1[M], uint32_t large2[M]) { 925 | uint32_t rnd1, rnd2, j; 926 | srand(i); 927 | if (i == 0) { 928 | for (j = 0; j < M / 2; j++) { 929 | rnd1 = 2 * j; 930 | rnd2 = 2 * j + 1; 931 | large1[j] = (rnd1 & 0xffff) + ((rnd2 & 0xffff) << 16); 932 | large2[2 * j] = rnd1; 933 | large2[2 * j + 1] = rnd2; 934 | } 935 | } else { 936 | for (j = 0; j < M / 2; j++) { 937 | rnd1 = get_rand() & COEFFICIENT_ALL_ONES; 938 | rnd2 = get_rand() & COEFFICIENT_ALL_ONES; 939 | large1[j] = (rnd1 & 0xffff) + ((rnd2 & 0xffff) << 16); 940 | large2[2 * j] = rnd1; 941 | large2[2 * j + 1] = rnd2; 942 | } 943 | } 944 | } 945 | -------------------------------------------------------------------------------- /stm32f407-discovery-rlwe/startup_stm32f40xx.s: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f40xx.s 4 | * @author MCD Application Team 5 | * @version V1.1.0 6 | * @date 11-January-2013 7 | * @brief STM32F40xx/41xx Devices vector table for RIDE7 toolchain. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the initial PC == Reset_Handler, 11 | * - Set the vector table entries with the exceptions ISR address 12 | * - Configure the clock system and the external SRAM mounted on 13 | * STM324xG-EVAL board to be used as data memory (optional, 14 | * to be enabled by user) 15 | * - Branches to main in the C library (which eventually 16 | * calls main()). 17 | * After Reset the Cortex-M4 processor is in Thread mode, 18 | * priority is Privileged, and the Stack is set to Main. 19 | ****************************************************************************** 20 | * @attention 21 | * 22 | *

© COPYRIGHT 2013 STMicroelectronics

23 | * 24 | * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 25 | * You may not use this file except in compliance with the License. 26 | * You may obtain a copy of the License at: 27 | * 28 | * http://www.st.com/software_license_agreement_liberty_v2 29 | * 30 | * Unless required by applicable law or agreed to in writing, software 31 | * distributed under the License is distributed on an "AS IS" BASIS, 32 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 33 | * See the License for the specific language governing permissions and 34 | * limitations under the License. 35 | * 36 | ****************************************************************************** 37 | */ 38 | 39 | .syntax unified 40 | .cpu cortex-m3 41 | .fpu softvfp 42 | .thumb 43 | 44 | .global g_pfnVectors 45 | .global Default_Handler 46 | 47 | /* start address for the initialization values of the .data section. 48 | defined in linker script */ 49 | .word _sidata 50 | /* start address for the .data section. defined in linker script */ 51 | .word _sdata 52 | /* end address for the .data section. defined in linker script */ 53 | .word _edata 54 | /* start address for the .bss section. defined in linker script */ 55 | .word _sbss 56 | /* end address for the .bss section. defined in linker script */ 57 | .word _ebss 58 | /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ 59 | 60 | /** 61 | * @brief This is the code that gets called when the processor first 62 | * starts execution following a reset event. Only the absolutely 63 | * necessary set is performed, after which the application 64 | * supplied main() routine is called. 65 | * @param None 66 | * @retval : None 67 | */ 68 | 69 | .section .text.Reset_Handler 70 | .weak Reset_Handler 71 | .type Reset_Handler, %function 72 | Reset_Handler: 73 | 74 | /* Copy the data segment initializers from flash to SRAM */ 75 | movs r1, #0 76 | b LoopCopyDataInit 77 | 78 | CopyDataInit: 79 | ldr r3, =_sidata 80 | ldr r3, [r3, r1] 81 | str r3, [r0, r1] 82 | adds r1, r1, #4 83 | 84 | LoopCopyDataInit: 85 | ldr r0, =_sdata 86 | ldr r3, =_edata 87 | adds r2, r0, r1 88 | cmp r2, r3 89 | bcc CopyDataInit 90 | ldr r2, =_sbss 91 | b LoopFillZerobss 92 | /* Zero fill the bss segment. */ 93 | FillZerobss: 94 | movs r3, #0 95 | str r3, [r2], #4 96 | 97 | LoopFillZerobss: 98 | ldr r3, = _ebss 99 | cmp r2, r3 100 | bcc FillZerobss 101 | 102 | /* Call the clock system intitialization function.*/ 103 | bl SystemInit 104 | /* Call the application's entry point.*/ 105 | bl main 106 | bx lr 107 | .size Reset_Handler, .-Reset_Handler 108 | 109 | /** 110 | * @brief This is the code that gets called when the processor receives an 111 | * unexpected interrupt. This simply enters an infinite loop, preserving 112 | * the system state for examination by a debugger. 113 | * @param None 114 | * @retval None 115 | */ 116 | .section .text.Default_Handler,"ax",%progbits 117 | Default_Handler: 118 | Infinite_Loop: 119 | b Infinite_Loop 120 | .size Default_Handler, .-Default_Handler 121 | /****************************************************************************** 122 | * 123 | * The minimal vector table for a Cortex M3. Note that the proper constructs 124 | * must be placed on this to ensure that it ends up at physical address 125 | * 0x0000.0000. 126 | * 127 | *******************************************************************************/ 128 | .section .isr_vector,"a",%progbits 129 | .type g_pfnVectors, %object 130 | .size g_pfnVectors, .-g_pfnVectors 131 | 132 | 133 | g_pfnVectors: 134 | .word _estack 135 | .word Reset_Handler 136 | .word NMI_Handler 137 | .word HardFault_Handler 138 | .word MemManage_Handler 139 | .word BusFault_Handler 140 | .word UsageFault_Handler 141 | .word 0 142 | .word 0 143 | .word 0 144 | .word 0 145 | .word SVC_Handler 146 | .word DebugMon_Handler 147 | .word 0 148 | .word PendSV_Handler 149 | .word SysTick_Handler 150 | 151 | /* External Interrupts */ 152 | .word WWDG_IRQHandler /* Window WatchDog */ 153 | .word PVD_IRQHandler /* PVD through EXTI Line detection */ 154 | .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ 155 | .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ 156 | .word FLASH_IRQHandler /* FLASH */ 157 | .word RCC_IRQHandler /* RCC */ 158 | .word EXTI0_IRQHandler /* EXTI Line0 */ 159 | .word EXTI1_IRQHandler /* EXTI Line1 */ 160 | .word EXTI2_IRQHandler /* EXTI Line2 */ 161 | .word EXTI3_IRQHandler /* EXTI Line3 */ 162 | .word EXTI4_IRQHandler /* EXTI Line4 */ 163 | .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ 164 | .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ 165 | .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ 166 | .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ 167 | .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ 168 | .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ 169 | .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ 170 | .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ 171 | .word CAN1_TX_IRQHandler /* CAN1 TX */ 172 | .word CAN1_RX0_IRQHandler /* CAN1 RX0 */ 173 | .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ 174 | .word CAN1_SCE_IRQHandler /* CAN1 SCE */ 175 | .word EXTI9_5_IRQHandler /* External Line[9:5]s */ 176 | .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ 177 | .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ 178 | .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ 179 | .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ 180 | .word TIM2_IRQHandler /* TIM2 */ 181 | .word TIM3_IRQHandler /* TIM3 */ 182 | .word TIM4_IRQHandler /* TIM4 */ 183 | .word I2C1_EV_IRQHandler /* I2C1 Event */ 184 | .word I2C1_ER_IRQHandler /* I2C1 Error */ 185 | .word I2C2_EV_IRQHandler /* I2C2 Event */ 186 | .word I2C2_ER_IRQHandler /* I2C2 Error */ 187 | .word SPI1_IRQHandler /* SPI1 */ 188 | .word SPI2_IRQHandler /* SPI2 */ 189 | .word USART1_IRQHandler /* USART1 */ 190 | .word USART2_IRQHandler /* USART2 */ 191 | .word USART3_IRQHandler /* USART3 */ 192 | .word EXTI15_10_IRQHandler /* External Line[15:10]s */ 193 | .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ 194 | .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ 195 | .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ 196 | .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ 197 | .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ 198 | .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */ 199 | .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ 200 | .word FSMC_IRQHandler /* FSMC */ 201 | .word SDIO_IRQHandler /* SDIO */ 202 | .word TIM5_IRQHandler /* TIM5 */ 203 | .word SPI3_IRQHandler /* SPI3 */ 204 | .word UART4_IRQHandler /* UART4 */ 205 | .word UART5_IRQHandler /* UART5 */ 206 | .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ 207 | .word TIM7_IRQHandler /* TIM7 */ 208 | .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ 209 | .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ 210 | .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ 211 | .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ 212 | .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ 213 | .word ETH_IRQHandler /* Ethernet */ 214 | .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ 215 | .word CAN2_TX_IRQHandler /* CAN2 TX */ 216 | .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ 217 | .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ 218 | .word CAN2_SCE_IRQHandler /* CAN2 SCE */ 219 | .word OTG_FS_IRQHandler /* USB OTG FS */ 220 | .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ 221 | .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ 222 | .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ 223 | .word USART6_IRQHandler /* USART6 */ 224 | .word I2C3_EV_IRQHandler /* I2C3 event */ 225 | .word I2C3_ER_IRQHandler /* I2C3 error */ 226 | .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ 227 | .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ 228 | .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ 229 | .word OTG_HS_IRQHandler /* USB OTG HS */ 230 | .word DCMI_IRQHandler /* DCMI */ 231 | .word CRYP_IRQHandler /* CRYP crypto */ 232 | .word HASH_RNG_IRQHandler /* Hash and Rng */ 233 | .word FPU_IRQHandler /* FPU */ 234 | 235 | /******************************************************************************* 236 | * 237 | * Provide weak aliases for each Exception handler to the Default_Handler. 238 | * As they are weak aliases, any function with the same name will override 239 | * this definition. 240 | * 241 | *******************************************************************************/ 242 | .weak NMI_Handler 243 | .thumb_set NMI_Handler,Default_Handler 244 | 245 | .weak HardFault_Handler 246 | .thumb_set HardFault_Handler,Default_Handler 247 | 248 | .weak MemManage_Handler 249 | .thumb_set MemManage_Handler,Default_Handler 250 | 251 | .weak BusFault_Handler 252 | .thumb_set BusFault_Handler,Default_Handler 253 | 254 | .weak UsageFault_Handler 255 | .thumb_set UsageFault_Handler,Default_Handler 256 | 257 | .weak SVC_Handler 258 | .thumb_set SVC_Handler,Default_Handler 259 | 260 | .weak DebugMon_Handler 261 | .thumb_set DebugMon_Handler,Default_Handler 262 | 263 | .weak PendSV_Handler 264 | .thumb_set PendSV_Handler,Default_Handler 265 | 266 | .weak SysTick_Handler 267 | .thumb_set SysTick_Handler,Default_Handler 268 | 269 | .weak WWDG_IRQHandler 270 | .thumb_set WWDG_IRQHandler,Default_Handler 271 | 272 | .weak PVD_IRQHandler 273 | .thumb_set PVD_IRQHandler,Default_Handler 274 | 275 | .weak TAMP_STAMP_IRQHandler 276 | .thumb_set TAMP_STAMP_IRQHandler,Default_Handler 277 | 278 | .weak RTC_WKUP_IRQHandler 279 | .thumb_set RTC_WKUP_IRQHandler,Default_Handler 280 | 281 | .weak FLASH_IRQHandler 282 | .thumb_set FLASH_IRQHandler,Default_Handler 283 | 284 | .weak RCC_IRQHandler 285 | .thumb_set RCC_IRQHandler,Default_Handler 286 | 287 | .weak EXTI0_IRQHandler 288 | .thumb_set EXTI0_IRQHandler,Default_Handler 289 | 290 | .weak EXTI1_IRQHandler 291 | .thumb_set EXTI1_IRQHandler,Default_Handler 292 | 293 | .weak EXTI2_IRQHandler 294 | .thumb_set EXTI2_IRQHandler,Default_Handler 295 | 296 | .weak EXTI3_IRQHandler 297 | .thumb_set EXTI3_IRQHandler,Default_Handler 298 | 299 | .weak EXTI4_IRQHandler 300 | .thumb_set EXTI4_IRQHandler,Default_Handler 301 | 302 | .weak DMA1_Stream0_IRQHandler 303 | .thumb_set DMA1_Stream0_IRQHandler,Default_Handler 304 | 305 | .weak DMA1_Stream1_IRQHandler 306 | .thumb_set DMA1_Stream1_IRQHandler,Default_Handler 307 | 308 | .weak DMA1_Stream2_IRQHandler 309 | .thumb_set DMA1_Stream2_IRQHandler,Default_Handler 310 | 311 | .weak DMA1_Stream3_IRQHandler 312 | .thumb_set DMA1_Stream3_IRQHandler,Default_Handler 313 | 314 | .weak DMA1_Stream4_IRQHandler 315 | .thumb_set DMA1_Stream4_IRQHandler,Default_Handler 316 | 317 | .weak DMA1_Stream5_IRQHandler 318 | .thumb_set DMA1_Stream5_IRQHandler,Default_Handler 319 | 320 | .weak DMA1_Stream6_IRQHandler 321 | .thumb_set DMA1_Stream6_IRQHandler,Default_Handler 322 | 323 | .weak ADC_IRQHandler 324 | .thumb_set ADC_IRQHandler,Default_Handler 325 | 326 | .weak CAN1_TX_IRQHandler 327 | .thumb_set CAN1_TX_IRQHandler,Default_Handler 328 | 329 | .weak CAN1_RX0_IRQHandler 330 | .thumb_set CAN1_RX0_IRQHandler,Default_Handler 331 | 332 | .weak CAN1_RX1_IRQHandler 333 | .thumb_set CAN1_RX1_IRQHandler,Default_Handler 334 | 335 | .weak CAN1_SCE_IRQHandler 336 | .thumb_set CAN1_SCE_IRQHandler,Default_Handler 337 | 338 | .weak EXTI9_5_IRQHandler 339 | .thumb_set EXTI9_5_IRQHandler,Default_Handler 340 | 341 | .weak TIM1_BRK_TIM9_IRQHandler 342 | .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler 343 | 344 | .weak TIM1_UP_TIM10_IRQHandler 345 | .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler 346 | 347 | .weak TIM1_TRG_COM_TIM11_IRQHandler 348 | .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler 349 | 350 | .weak TIM1_CC_IRQHandler 351 | .thumb_set TIM1_CC_IRQHandler,Default_Handler 352 | 353 | .weak TIM2_IRQHandler 354 | .thumb_set TIM2_IRQHandler,Default_Handler 355 | 356 | .weak TIM3_IRQHandler 357 | .thumb_set TIM3_IRQHandler,Default_Handler 358 | 359 | .weak TIM4_IRQHandler 360 | .thumb_set TIM4_IRQHandler,Default_Handler 361 | 362 | .weak I2C1_EV_IRQHandler 363 | .thumb_set I2C1_EV_IRQHandler,Default_Handler 364 | 365 | .weak I2C1_ER_IRQHandler 366 | .thumb_set I2C1_ER_IRQHandler,Default_Handler 367 | 368 | .weak I2C2_EV_IRQHandler 369 | .thumb_set I2C2_EV_IRQHandler,Default_Handler 370 | 371 | .weak I2C2_ER_IRQHandler 372 | .thumb_set I2C2_ER_IRQHandler,Default_Handler 373 | 374 | .weak SPI1_IRQHandler 375 | .thumb_set SPI1_IRQHandler,Default_Handler 376 | 377 | .weak SPI2_IRQHandler 378 | .thumb_set SPI2_IRQHandler,Default_Handler 379 | 380 | .weak USART1_IRQHandler 381 | .thumb_set USART1_IRQHandler,Default_Handler 382 | 383 | .weak USART2_IRQHandler 384 | .thumb_set USART2_IRQHandler,Default_Handler 385 | 386 | .weak USART3_IRQHandler 387 | .thumb_set USART3_IRQHandler,Default_Handler 388 | 389 | .weak EXTI15_10_IRQHandler 390 | .thumb_set EXTI15_10_IRQHandler,Default_Handler 391 | 392 | .weak RTC_Alarm_IRQHandler 393 | .thumb_set RTC_Alarm_IRQHandler,Default_Handler 394 | 395 | .weak OTG_FS_WKUP_IRQHandler 396 | .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler 397 | 398 | .weak TIM8_BRK_TIM12_IRQHandler 399 | .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler 400 | 401 | .weak TIM8_UP_TIM13_IRQHandler 402 | .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler 403 | 404 | .weak TIM8_TRG_COM_TIM14_IRQHandler 405 | .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler 406 | 407 | .weak TIM8_CC_IRQHandler 408 | .thumb_set TIM8_CC_IRQHandler,Default_Handler 409 | 410 | .weak DMA1_Stream7_IRQHandler 411 | .thumb_set DMA1_Stream7_IRQHandler,Default_Handler 412 | 413 | .weak FSMC_IRQHandler 414 | .thumb_set FSMC_IRQHandler,Default_Handler 415 | 416 | .weak SDIO_IRQHandler 417 | .thumb_set SDIO_IRQHandler,Default_Handler 418 | 419 | .weak TIM5_IRQHandler 420 | .thumb_set TIM5_IRQHandler,Default_Handler 421 | 422 | .weak SPI3_IRQHandler 423 | .thumb_set SPI3_IRQHandler,Default_Handler 424 | 425 | .weak UART4_IRQHandler 426 | .thumb_set UART4_IRQHandler,Default_Handler 427 | 428 | .weak UART5_IRQHandler 429 | .thumb_set UART5_IRQHandler,Default_Handler 430 | 431 | .weak TIM6_DAC_IRQHandler 432 | .thumb_set TIM6_DAC_IRQHandler,Default_Handler 433 | 434 | .weak TIM7_IRQHandler 435 | .thumb_set TIM7_IRQHandler,Default_Handler 436 | 437 | .weak DMA2_Stream0_IRQHandler 438 | .thumb_set DMA2_Stream0_IRQHandler,Default_Handler 439 | 440 | .weak DMA2_Stream1_IRQHandler 441 | .thumb_set DMA2_Stream1_IRQHandler,Default_Handler 442 | 443 | .weak DMA2_Stream2_IRQHandler 444 | .thumb_set DMA2_Stream2_IRQHandler,Default_Handler 445 | 446 | .weak DMA2_Stream3_IRQHandler 447 | .thumb_set DMA2_Stream3_IRQHandler,Default_Handler 448 | 449 | .weak DMA2_Stream4_IRQHandler 450 | .thumb_set DMA2_Stream4_IRQHandler,Default_Handler 451 | 452 | .weak ETH_IRQHandler 453 | .thumb_set ETH_IRQHandler,Default_Handler 454 | 455 | .weak ETH_WKUP_IRQHandler 456 | .thumb_set ETH_WKUP_IRQHandler,Default_Handler 457 | 458 | .weak CAN2_TX_IRQHandler 459 | .thumb_set CAN2_TX_IRQHandler,Default_Handler 460 | 461 | .weak CAN2_RX0_IRQHandler 462 | .thumb_set CAN2_RX0_IRQHandler,Default_Handler 463 | 464 | .weak CAN2_RX1_IRQHandler 465 | .thumb_set CAN2_RX1_IRQHandler,Default_Handler 466 | 467 | .weak CAN2_SCE_IRQHandler 468 | .thumb_set CAN2_SCE_IRQHandler,Default_Handler 469 | 470 | .weak OTG_FS_IRQHandler 471 | .thumb_set OTG_FS_IRQHandler,Default_Handler 472 | 473 | .weak DMA2_Stream5_IRQHandler 474 | .thumb_set DMA2_Stream5_IRQHandler,Default_Handler 475 | 476 | .weak DMA2_Stream6_IRQHandler 477 | .thumb_set DMA2_Stream6_IRQHandler,Default_Handler 478 | 479 | .weak DMA2_Stream7_IRQHandler 480 | .thumb_set DMA2_Stream7_IRQHandler,Default_Handler 481 | 482 | .weak USART6_IRQHandler 483 | .thumb_set USART6_IRQHandler,Default_Handler 484 | 485 | .weak I2C3_EV_IRQHandler 486 | .thumb_set I2C3_EV_IRQHandler,Default_Handler 487 | 488 | .weak I2C3_ER_IRQHandler 489 | .thumb_set I2C3_ER_IRQHandler,Default_Handler 490 | 491 | .weak OTG_HS_EP1_OUT_IRQHandler 492 | .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler 493 | 494 | .weak OTG_HS_EP1_IN_IRQHandler 495 | .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler 496 | 497 | .weak OTG_HS_WKUP_IRQHandler 498 | .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler 499 | 500 | .weak OTG_HS_IRQHandler 501 | .thumb_set OTG_HS_IRQHandler,Default_Handler 502 | 503 | .weak DCMI_IRQHandler 504 | .thumb_set DCMI_IRQHandler,Default_Handler 505 | 506 | .weak CRYP_IRQHandler 507 | .thumb_set CRYP_IRQHandler,Default_Handler 508 | 509 | .weak HASH_RNG_IRQHandler 510 | .thumb_set HASH_RNG_IRQHandler,Default_Handler 511 | 512 | .weak FPU_IRQHandler 513 | .thumb_set FPU_IRQHandler,Default_Handler 514 | 515 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 516 | --------------------------------------------------------------------------------