From f9aab3b79f9f4fc2853587c3c61a787f96b08bba Mon Sep 17 00:00:00 2001 From: www-git-cn <102035872+www-git-cn@users.noreply.github.com> Date: Sun, 28 Apr 2024 23:29:26 +0800 Subject: [PATCH] some bugs fixed --- .gitignore | 5 + CMakeLists.txt | 6 +- CMakeLists.txt.user | 418 ------ ecurve.cpp => ecurve.c | 0 ecurve.h | 4 +- generator_cgo/.idea/.gitignore | 8 - generator_cgo/.idea/.name | 1 - generator_cgo/.idea/cgo.iml | 9 - generator_cgo/.idea/modules.xml | 8 - generator_cgo/.vscode/tasks.json | 18 - generator_cgo/go.mod | 3 - generator_cgo/go.sum | 0 generator_cgo/include/big.h | 451 ------ generator_cgo/include/brick.h | 36 - generator_cgo/include/crt.h | 39 - generator_cgo/include/ebrick.h | 37 - generator_cgo/include/ebrick2.h | 36 - generator_cgo/include/ec2.h | 146 -- generator_cgo/include/ecn.h | 159 -- generator_cgo/include/ecnzzn.h | 22 - generator_cgo/include/ecurve.cpp | 70 - generator_cgo/include/ecurve.h | 23 - generator_cgo/include/flash.h | 163 -- generator_cgo/include/floating.h | 94 -- generator_cgo/include/gf2m.h | 171 --- generator_cgo/include/hash.h | 24 - generator_cgo/include/kgc.h | 22 - generator_cgo/include/miracl.h | 1563 -------------------- generator_cgo/include/mirdef.h | 15 - generator_cgo/include/sign.h | 39 - generator_cgo/include/utils.h | 24 - generator_cgo/include/zzn.h | 219 --- generator_cgo/lib/libKGC.a | Bin 14968 -> 0 bytes generator_cgo/lib/libKGCAll.a | Bin 11276 -> 0 bytes generator_cgo/lib/libMiracl.a | Bin 418988 -> 0 bytes generator_cgo/main.go | 112 -- generator_cgo/params.txt | 19 - generator_cgo/include/hash.cpp => hash.c | 0 hash.cpp | 61 - hash.h | 4 +- generator_cgo/include/kgc.cpp => kgc.c | 0 kgc.cpp | 84 -- miracl/CMakeLists.txt | 2 +- generator_cgo/include/sign.cpp => sign.c | 0 sign.cpp | 107 -- generator_cgo/include/utils.cpp => utils.c | 0 utils.cpp | 76 - utils.h | 3 - 48 files changed, 11 insertions(+), 4290 deletions(-) delete mode 100644 CMakeLists.txt.user rename ecurve.cpp => ecurve.c (100%) delete mode 100644 generator_cgo/.idea/.gitignore delete mode 100644 generator_cgo/.idea/.name delete mode 100644 generator_cgo/.idea/cgo.iml delete mode 100644 generator_cgo/.idea/modules.xml delete mode 100644 generator_cgo/.vscode/tasks.json delete mode 100644 generator_cgo/go.mod delete mode 100644 generator_cgo/go.sum delete mode 100644 generator_cgo/include/big.h delete mode 100644 generator_cgo/include/brick.h delete mode 100644 generator_cgo/include/crt.h delete mode 100644 generator_cgo/include/ebrick.h delete mode 100644 generator_cgo/include/ebrick2.h delete mode 100644 generator_cgo/include/ec2.h delete mode 100644 generator_cgo/include/ecn.h delete mode 100644 generator_cgo/include/ecnzzn.h delete mode 100644 generator_cgo/include/ecurve.cpp delete mode 100644 generator_cgo/include/ecurve.h delete mode 100644 generator_cgo/include/flash.h delete mode 100644 generator_cgo/include/floating.h delete mode 100644 generator_cgo/include/gf2m.h delete mode 100644 generator_cgo/include/hash.h delete mode 100644 generator_cgo/include/kgc.h delete mode 100644 generator_cgo/include/miracl.h delete mode 100644 generator_cgo/include/mirdef.h delete mode 100644 generator_cgo/include/sign.h delete mode 100644 generator_cgo/include/utils.h delete mode 100644 generator_cgo/include/zzn.h delete mode 100644 generator_cgo/lib/libKGC.a delete mode 100644 generator_cgo/lib/libKGCAll.a delete mode 100644 generator_cgo/lib/libMiracl.a delete mode 100644 generator_cgo/main.go delete mode 100644 generator_cgo/params.txt rename generator_cgo/include/hash.cpp => hash.c (100%) delete mode 100644 hash.cpp rename generator_cgo/include/kgc.cpp => kgc.c (100%) delete mode 100644 kgc.cpp rename generator_cgo/include/sign.cpp => sign.c (100%) delete mode 100644 sign.cpp rename generator_cgo/include/utils.cpp => utils.c (100%) delete mode 100644 utils.cpp diff --git a/.gitignore b/.gitignore index adf8f72..96418f4 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,8 @@ # Go workspace file go.work +# QtCreator CMake +CMakeLists.txt.user* + +#CMake +build/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index deaefb0..fb2ad1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.21.0) -project(KGC) +project(KGC LANGUAGES C) include(GNUInstallDirs) @@ -52,7 +52,7 @@ elseif(WIN32) COMMAND cd "${CMAKE_CURRENT_BINARY_DIR}/output/temp" COMMAND ${CMAKE_AR} x "${CMAKE_CURRENT_BINARY_DIR}/output/temp/libMiracl.a" COMMAND ${CMAKE_AR} x "${CMAKE_CURRENT_BINARY_DIR}/output/temp/lib${PROJECT_NAME}.a" - COMMAND ${CMAKE_AR} crs "${CMAKE_CURRENT_BINARY_DIR}/output/lib/lib${PROJECT_NAME}All.a" "${CMAKE_CURRENT_BINARY_DIR}/output/temp/*.obj" + COMMAND ${CMAKE_AR} crs "${CMAKE_CURRENT_BINARY_DIR}/output/lib/lib${PROJECT_NAME}All.a" "*.obj" DEPENDS ${PROJECT_NAME} Miracl ) else() @@ -63,7 +63,7 @@ else() COMMAND cd "${CMAKE_CURRENT_BINARY_DIR}/output/temp" COMMAND ${CMAKE_AR} x "${CMAKE_CURRENT_BINARY_DIR}/output/temp/libMiracl.a" COMMAND ${CMAKE_AR} x "${CMAKE_CURRENT_BINARY_DIR}/output/temp/lib${PROJECT_NAME}.a" - COMMAND ${CMAKE_AR} crs "${CMAKE_CURRENT_BINARY_DIR}/output/lib/lib${PROJECT_NAME}All.a" "${CMAKE_CURRENT_BINARY_DIR}/output/temp/*.o" + COMMAND ${CMAKE_AR} crs "${CMAKE_CURRENT_BINARY_DIR}/output/lib/lib${PROJECT_NAME}All.a" "*.o" DEPENDS ${PROJECT_NAME} Miracl ) endif() diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user deleted file mode 100644 index 9e23732..0000000 --- a/CMakeLists.txt.user +++ /dev/null @@ -1,418 +0,0 @@ - - - - - - EnvironmentId - {7795ecad-0ea3-4fc2-a933-fbc01bf1ad55} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - 0 - false - true - false - 2 - true - true - 0 - 8 - true - false - 1 - true - true - true - *.md, *.MD, Makefile - false - true - true - - - - ProjectExplorer.Project.PluginSettings - - - true - false - true - true - true - true - - - 0 - true - - true - true - Builtin.DefaultTidyAndClazy - 2 - true - - - - true - - - - - ProjectExplorer.Project.Target.0 - - Desktop - Desktop Qt 6.5.3 MinGW 64-bit - Desktop Qt 6.5.3 MinGW 64-bit - qt.qt6.653.win64_mingw_kit - 0 - 0 - 0 - - Debug - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=Debug --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - 0 - C:\KGC\build\Desktop_Qt_6_5_3_MinGW_64_bit-Debug - - - - - all - - false - - true - 构建 - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - 构建 - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Debug - CMakeProjectManager.CMakeBuildConfiguration - - - Release - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=Release --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - C:\KGC\build\Desktop_Qt_6_5_3_MinGW_64_bit-Release - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release - CMakeProjectManager.CMakeBuildConfiguration - - - RelWithDebInfo - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - C:\KGC\build\Desktop_Qt_6_5_3_MinGW_64_bit-RelWithDebInfo - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Release with Debug Information - CMakeProjectManager.CMakeBuildConfiguration - - - RelWithDebInfo - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - 0 - C:\KGC\build\Desktop_Qt_6_5_3_MinGW_64_bit-Profile - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Profile - CMakeProjectManager.CMakeBuildConfiguration - - - MinSizeRel - 2 - false - - -DCMAKE_GENERATOR:STRING=Ninja --DCMAKE_BUILD_TYPE:STRING=MinSizeRel --DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake --DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable} --DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX} --DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C} --DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx} --DCMAKE_CXX_FLAGS_INIT:STRING=%{Qt:QML_DEBUG_FLAG} - C:\KGC\build\Desktop_Qt_6_5_3_MinGW_64_bit-MinSizeRel - - - - - all - - false - - true - CMakeProjectManager.MakeStep - - 1 - 构建 - 构建 - ProjectExplorer.BuildSteps.Build - - - - - - clean - - false - - true - CMakeProjectManager.MakeStep - - 1 - 清除 - 清除 - ProjectExplorer.BuildSteps.Clean - - 2 - false - - false - - Minimum Size Release - CMakeProjectManager.CMakeBuildConfiguration - - 5 - - - 0 - 部署 - 部署 - ProjectExplorer.BuildSteps.Deploy - - 1 - - false - ProjectExplorer.DefaultDeployConfiguration - - 1 - - true - true - 0 - true - - 2 - - false - -e cpu-cycles --call-graph "dwarf,4096" -F 250 - - ProjectExplorer.CustomExecutableRunConfiguration - - false - true - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 22 - - - Version - 22 - - diff --git a/ecurve.cpp b/ecurve.c similarity index 100% rename from ecurve.cpp rename to ecurve.c diff --git a/ecurve.h b/ecurve.h index 42c286e..540bbc3 100644 --- a/ecurve.h +++ b/ecurve.h @@ -1,11 +1,9 @@ #ifndef __ECURVE_H__ #define __ECURVE_H__ -extern "C" -{ +#include #include "miracl.h" #include "mirdef.h" -} typedef struct ecc_params { diff --git a/generator_cgo/.idea/.gitignore b/generator_cgo/.idea/.gitignore deleted file mode 100644 index 13566b8..0000000 --- a/generator_cgo/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/generator_cgo/.idea/.name b/generator_cgo/.idea/.name deleted file mode 100644 index 30de634..0000000 --- a/generator_cgo/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -main.go \ No newline at end of file diff --git a/generator_cgo/.idea/cgo.iml b/generator_cgo/.idea/cgo.iml deleted file mode 100644 index 5e764c4..0000000 --- a/generator_cgo/.idea/cgo.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/generator_cgo/.idea/modules.xml b/generator_cgo/.idea/modules.xml deleted file mode 100644 index 5f95085..0000000 --- a/generator_cgo/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/generator_cgo/.vscode/tasks.json b/generator_cgo/.vscode/tasks.json deleted file mode 100644 index 38de289..0000000 --- a/generator_cgo/.vscode/tasks.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "type": "go", - "label": "go: build package", - "command": "build", - "args": [ - "${fileDirname}" - ], - "problemMatcher": [ - "$go" - ], - "group": "build", - "detail": "cd c:\\Users\\25761\\Desktop\\cgo; go build ${fileDirname}" - } - ] -} \ No newline at end of file diff --git a/generator_cgo/go.mod b/generator_cgo/go.mod deleted file mode 100644 index e26fe90..0000000 --- a/generator_cgo/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module example.com/m/v2 - -go 1.20 diff --git a/generator_cgo/go.sum b/generator_cgo/go.sum deleted file mode 100644 index e69de29..0000000 diff --git a/generator_cgo/include/big.h b/generator_cgo/include/big.h deleted file mode 100644 index bbc2b25..0000000 --- a/generator_cgo/include/big.h +++ /dev/null @@ -1,451 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox UK Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * - * MIRACL C++ Header file big.h - * - * AUTHOR : N.Coghlan - * Modified by M.Scott - * - * PURPOSE : Definition of class Big - * - * Bigs are normally created on the heap, but by defining BIGS=m - * on the compiler command line, Bigs are instead mostly created from the - * stack. Note that m must be same or less than the n in the main program - * with for example - * - * Miracl precison(n,0); - * - * where n is the (fixed) size in words of each Big. - * - * This may be faster, as C++ tends to create and destroy lots of - * temporaries. Especially recommended if m is small. Do not use - * for program development - * - * However Bigs created from a string are always allocated from the heap. - * This is useful for creating large read-only constants which are larger - * than m. - * - * NOTE:- I/O conversion - * - * To convert a hex character string to a Big - * - * Big x; - * char c[100]; - * - * mip->IOBASE=16; - * x=c; - * - * To convert a Big to a hex character string - * - * mip->IOBASE=16; - * c << x; - * - * To convert to/from pure binary, see the from_binary() - * and to_binary() friend functions. - * - * int len; - * char c[100]; - * ... - * Big x=from_binary(len,c); // creates Big x from len bytes of binary in c - * - * len=to_binary(x,100,c,FALSE); // converts Big x to len bytes binary in c[100] - * len=to_binary(x,100,c,TRUE); // converts Big x to len bytes binary in c[100] - * // (right justified with leading zeros) - */ - -#ifndef BIG_H -#define BIG_H - -#include -//#include -#include - -#include "mirdef.h" - -#ifdef MR_CPP -#include "miracl.h" -#else -extern "C" -{ - #include "miracl.h" -} -#endif - -#ifndef MR_NO_STANDARD_IO -#include -using std::istream; -using std::ostream; -#endif - -#ifndef MIRACL_CLASS -#define MIRACL_CLASS - -#ifdef __cplusplus -#ifdef MR_GENERIC_MT -#error "The generic method isn't supported for C++, its C only" -#endif -#endif - -class Miracl -{ /* dummy class to initialise MIRACL - MUST be called before any Bigs * - * are created. This could be a problem for static/global data declared * - * in modules other than the main module */ - miracl *mr; -public: - Miracl(int nd,mr_small nb=0) - {mr=mirsys(nd,nb); -#ifdef MR_FLASH -mr->RPOINT=TRUE; -#endif -} - miracl *operator&() {return mr;} - ~Miracl() {mirexit();} -}; - -#endif - -/* -#ifdef BIGS -#define MR_INIT_BIG memset(mem,0,mr_big_reserve(1,BIGS)); fn=(big)mirvar_mem_variable(mem,0,BIGS); -#else -#define MR_INIT_BIG mem=(char *)memalloc(1); fn=(big)mirvar_mem(mem,0); -#endif -*/ - -#ifdef BIGS -#define MR_INIT_BIG fn=&b; b.w=a; b.len=0; for (int i=0;ilen=1; fn->w[0]=s; return *this;} - Big& operator=(const Big& b) {copy(b.fn,fn); return *this;} - Big& operator=(big& b) {copy(b,fn); return *this;} - Big& operator=(big* b) {fn=*b; return *this;} -#ifndef MR_SIMPLE_IO -#ifdef MR_SIMPLE_BASE - Big& operator=(char* s){instr(fn,s);return *this;} -#else - Big& operator=(char* s){cinstr(fn,s);return *this;} -#endif -#endif - Big& operator++() {incr(fn,1,fn); return *this;} - Big& operator--() {decr(fn,1,fn); return *this;} - Big& operator+=(int i) {incr(fn,i,fn); return *this;} - Big& operator+=(const Big& b){add(fn,b.fn,fn); return *this;} - - Big& operator-=(int i) {decr(fn,i,fn); return *this;} - Big& operator-=(const Big& b) {subtract(fn,b.fn,fn); return *this;} - - Big& operator*=(int i) {premult(fn,i,fn); return *this;} - Big& operator*=(const Big& b) {multiply(fn,b.fn,fn); return *this;} - - Big& operator/=(int i) {subdiv(fn,i,fn); return *this;} - Big& operator/=(const Big& b) {divide(fn,b.fn,fn); return *this;} - - Big& operator%=(int i) {convert(subdiv(fn,i,fn),fn); return *this;} - Big& operator%=(const Big& b) {divide(fn,b.fn,b.fn); return *this;} - - Big& operator<<=(int i) {sftbit(fn,i,fn); return *this;} - Big& operator>>=(int i) {sftbit(fn,-i,fn); return *this;} - - Big& shift(int n) {mr_shift(fn,n,fn); return *this;} - - mr_small& operator[](int i) {return fn->w[i];} - - void negate() const; - BOOL iszero() const; - BOOL isone() const; - int get(int index) { int m; m=getdig(fn,index); return m; } - void set(int index,int n) { putdig(n,fn,index);} - int len() const; - - big getbig() const; - - friend class Flash; - - friend Big operator-(const Big&); - - friend Big operator+(const Big&,int); - friend Big operator+(int,const Big&); - friend Big operator+(const Big&,const Big&); - - friend Big operator-(const Big&, int); - friend Big operator-(int,const Big&); - friend Big operator-(const Big&,const Big&); - - friend Big operator*(const Big&, int); - friend Big operator*(int,const Big&); - friend Big operator*(const Big&,const Big&); - - friend BOOL fmth(int n,const Big&,const Big&,Big&); // fast mult - top half - - friend Big operator/(const Big&,int); - friend Big operator/(const Big&,const Big&); - - friend int operator%(const Big&, int); - friend Big operator%(const Big&, const Big&); - - friend Big operator<<(const Big&, int); - friend Big operator>>(const Big&, int); - - friend BOOL operator<=(const Big& b1,const Big& b2) - {if (mr_compare(b1.fn,b2.fn)<=0) return TRUE; else return FALSE;} - friend BOOL operator>=(const Big& b1,const Big& b2) - {if (mr_compare(b1.fn,b2.fn)>=0) return TRUE; else return FALSE;} - friend BOOL operator==(const Big& b1,const Big& b2) - {if (mr_compare(b1.fn,b2.fn)==0) return TRUE; else return FALSE;} - friend BOOL operator!=(const Big& b1,const Big& b2) - {if (mr_compare(b1.fn,b2.fn)!=0) return TRUE; else return FALSE;} - friend BOOL operator<(const Big& b1,const Big& b2) - {if (mr_compare(b1.fn,b2.fn)<0) return TRUE; else return FALSE;} - friend BOOL operator>(const Big& b1,const Big& b2) - {if (mr_compare(b1.fn,b2.fn)>0) return TRUE; else return FALSE;} - - friend Big from_binary(int,char *); - - friend int to_binary(const Big& b,int max,char *ptr,BOOL justify=FALSE) - { - return big_to_bytes(max,b.fn,ptr,justify); - } - //friend int to_binary(const Big&,int,char *,BOOL justify=FALSE); - friend Big modmult(const Big&,const Big&,const Big&); - friend Big mad(const Big&,const Big&,const Big&,const Big&,Big&); - friend Big norm(const Big&); - friend Big sqrt(const Big&); - friend Big root(const Big&,int); - friend Big gcd(const Big&,const Big&); - friend void set_zzn3(int cnr,Big& sru) {get_mip()->cnr=cnr; nres(sru.fn,get_mip()->sru);} - friend int recode(const Big& e,int t,int w,int i) {return recode(e.fn,t,w,i);} - -#ifndef MR_FP - friend Big land(const Big&,const Big&); // logical AND - friend Big lxor(const Big&,const Big&); // logical XOR -#endif - friend Big pow(const Big&,int); // x^m - friend Big pow(const Big&, int, const Big&); // x^m mod n - friend Big pow(int, const Big&, const Big&); // x^m mod n - friend Big pow(const Big&, const Big&, const Big&); // x^m mod n - friend Big pow(const Big&, const Big&, const Big&, const Big&, const Big&); - // x^m.y^k mod n - friend Big pow(int,Big *,Big *,Big); // x[0]^m[0].x[1].m[1]... mod n - - friend Big luc(const Big& b1,const Big& b2, const Big& b3, Big *b4=NULL) - { - Big z; if (b4!=NULL) lucas(b1.fn,b2.fn,b3.fn,b4->fn,z.fn); - else lucas(b1.fn,b2.fn,b3.fn,z.fn,z.fn); - return z; - } - //friend Big luc(const Big& ,const Big&, const Big&, Big *b4=NULL); - friend Big moddiv(const Big&,const Big&,const Big&); - friend Big inverse(const Big&, const Big&); - friend void multi_inverse(int,Big*,const Big&,Big *); -#ifndef MR_NO_RAND - friend Big rand(const Big&); // 0 < rand < parameter - friend Big rand(int,int); // (digits,base) e.g. (32,16) - friend Big randbits(int); // n random bits - friend Big strong_rand(csprng *,const Big&); - friend Big strong_rand(csprng *,int,int); -#endif - friend Big abs(const Big&); -// This next only works if MIRACL is using a binary base... - friend int bit(const Big& b,int i) {return mr_testbit(b.fn,i);} - friend int bits(const Big& b) {return logb2(b.fn);} - friend int ham(const Big& b) {return hamming(b.fn);} - friend int jacobi(const Big& b1,const Big& b2) {return jack(b1.fn,b2.fn);} - friend int toint(const Big& b) {return size(b.fn);} - friend BOOL prime(const Big& b) {return isprime(b.fn);} - friend Big nextprime(const Big&); - friend Big nextsafeprime(int type,int subset,const Big&); - friend Big trial_divide(const Big& b); - friend BOOL small_factors(const Big& b); - friend BOOL perfect_power(const Big& b); - friend Big sqrt(const Big&,const Big&); - - friend void ecurve(const Big&,const Big&,const Big&,int); - friend BOOL ecurve2(int,int,int,int,const Big&,const Big&,BOOL,int); - friend BOOL is_on_curve(const Big&); - friend void modulo(const Big&); - friend BOOL modulo(int,int,int,int,BOOL); - friend Big get_modulus(void); - friend int window(const Big& x,int i,int* nbs,int *nzs,int window_size=5) - { - return mr_window(x.fn,i,nbs,nzs,window_size); - } - - - //friend int window(const Big&,int,int*,int*,int window_size=5); - friend int naf_window(const Big& x,const Big& x3,int i,int* nbs,int* nzs,int store=11) - { - return mr_naf_window(x.fn,x3.fn,i,nbs,nzs,store); - } - - - //friend int naf_window(const Big&,const Big&,int,int*,int*,int store=11); - friend void jsf(const Big&,const Big&,Big&,Big&,Big&,Big&); - -/* Montgomery stuff */ - - friend Big nres(const Big&); - friend Big redc(const Big&); -/* - friend Big nres_negate(const Big&); - friend Big nres_modmult(const Big&,const Big&); - friend Big nres_premult(const Big&,int); - friend Big nres_pow(const Big&,const Big&); - friend Big nres_pow2(const Big&,const Big&,const Big&,const Big&); - friend Big nres_pown(int,Big *,Big *); - friend Big nres_luc(const Big&,const Big&,Big *b3=NULL); - friend Big nres_sqrt(const Big&); - friend Big nres_modadd(const Big&,const Big&); - friend Big nres_modsub(const Big&,const Big&); - friend Big nres_moddiv(const Big&,const Big&); -*/ -/* these are faster.... */ -/* - friend void nres_modmult(Big& a,const Big& b,Big& c) - {nres_modmult(a.fn,b.fn,c.fn);} - friend void nres_modadd(Big& a,const Big& b,Big& c) - {nres_modadd(a.fn,b.fn,c.fn);} - friend void nres_modsub(Big& a,const Big& b,Big& c) - {nres_modsub(a.fn,b.fn,c.fn);} - friend void nres_negate(Big& a,Big& b) - {nres_negate(a.fn,b.fn);} - friend void nres_premult(Big& a,int b,Big& c) - {nres_premult(a.fn,b,c.fn);} - friend void nres_moddiv(Big & a,const Big& b,Big& c) - {nres_moddiv(a.fn,b.fn,c.fn);} -*/ - friend Big shift(const Big&b,int n); - friend int length(const Big&b); - - -/* Note that when inputting text as a number the CR is NOT * - * included in the text, unlike C I/O which does include CR. */ - -#ifndef MR_NO_STANDARD_IO - - friend istream& operator>>(istream&, Big&); - friend ostream& operator<<(ostream&, const Big&); - friend ostream& otfloat(ostream&,const Big&,int); - -#endif - -// output Big to a String - friend char * operator<<(char * s,const Big&); - - ~Big() { - // zero(fn); -#ifndef BIGS - mr_free(fn); -#endif - } -}; - -extern BOOL modulo(int,int,int,int,BOOL); -extern Big get_modulus(void); -extern Big rand(int,int); -extern Big strong_rand(csprng *,int,int); -extern Big from_binary(int,char *); -//extern int to_binary(const Big&,int,char *,BOOL); - -using namespace std; - -#endif - diff --git a/generator_cgo/include/brick.h b/generator_cgo/include/brick.h deleted file mode 100644 index bf06b4b..0000000 --- a/generator_cgo/include/brick.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * MIRACL C++ Header file brick.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class Brick - * Comb method for fast exponentiation with - * precomputation - * NOTE : Must be used in conjunction with big.cpp - * - */ - -#ifndef BRICK_H -#define BRICK_H - -#include "big.h" - -class Brick -{ - BOOL created; - brick b; -public: - Brick(Big g,Big n,int window,int nb) - {brick_init(&b,g.getbig(),n.getbig(),window,nb); created=TRUE;} - - Brick(brick *bb) { b=*bb; created=FALSE; } - - brick *get(void) {return &b;} - - Big pow(Big &e) {Big w; pow_brick(&b,e.getbig(),w.getbig()); return w;} - - ~Brick() {if (created) brick_end(&b);} -}; - -#endif - diff --git a/generator_cgo/include/crt.h b/generator_cgo/include/crt.h deleted file mode 100644 index 65e7ea2..0000000 --- a/generator_cgo/include/crt.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * MIRACL C++ Header file crt.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class Crt (Chinese Remainder Thereom) - * NOTE : Must be used in conjunction with big.cpp - * Can be used with either Big or utype moduli - */ - -#ifndef CRT_H -#define CRT_H - -#include "big.h" - -#define MR_CRT_BIG 0 -#define MR_CRT_SMALL 1 - -class Crt -{ - big_chinese bc; - small_chinese sc; - int type; -public: - Crt(int,Big *); - Crt(int,mr_utype *); - - Big eval(Big *); - Big eval(mr_utype *); - - ~Crt() - { /* destructor */ - if (type==MR_CRT_BIG) crt_end(&bc); - if (type==MR_CRT_SMALL) scrt_end(&sc); - } -}; - -#endif - diff --git a/generator_cgo/include/ebrick.h b/generator_cgo/include/ebrick.h deleted file mode 100644 index f87effd..0000000 --- a/generator_cgo/include/ebrick.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * MIRACL C++ Header file ebrick.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class EBrick - * Brickell et al's method for fast exponentiation with - * precomputation - elliptic curve version GF(p) - * NOTE : Must be used in conjunction with big.cpp - * - */ - -#ifndef EBRICK_H -#define EBRICK_H - -#include "big.h" - -class EBrick -{ - BOOL created; - ebrick B; -public: - EBrick(Big x,Big y,Big a,Big b,Big n,int window,int nb) - {ebrick_init(&B,x.getbig(),y.getbig(),a.getbig(),b.getbig(),n.getbig(),window,nb); - created=TRUE;} - - EBrick(ebrick *b) {B=*b; created=FALSE;} /* set structure */ - - ebrick *get(void) {return &B;} /* get address of structure */ - - int mul(Big &e,Big &x,Big &y) {int d=mul_brick(&B,e.getbig(),x.getbig(),y.getbig()); return d;} - - ~EBrick() {if (created) ebrick_end(&B);} -}; - -#endif - diff --git a/generator_cgo/include/ebrick2.h b/generator_cgo/include/ebrick2.h deleted file mode 100644 index 1bd6b6a..0000000 --- a/generator_cgo/include/ebrick2.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * MIRACL C++ Header file ebrick2.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class EBrick2 - * Brickell et al's method for fast exponentiation with - * precomputation - elliptic curve version GF(2^m) - * NOTE : Must be used in conjunction with big.cpp - */ - -#ifndef EBRICK2_H -#define EBRICK2_H - -#include "big.h" - -class EBrick2 -{ - BOOL created; - ebrick2 B; -public: - EBrick2(Big x,Big y,Big a2,Big a6,int m,int a,int b,int c,int window,int nb) - {ebrick2_init(&B,x.getbig(),y.getbig(),a2.getbig(),a6.getbig(),m,a,b,c,window,nb); - created=TRUE;} - - EBrick2(ebrick2 *b) {B=*b; created=FALSE;} /* set structure */ - - ebrick2 *get(void) {return &B;} /* get address of structure */ - - int mul(Big &e,Big &x,Big &y) {int d=mul2_brick(&B,e.getbig(),x.getbig(),y.getbig()); return d;} - - ~EBrick2() {if (created) ebrick2_end(&B);} -}; - -#endif - diff --git a/generator_cgo/include/ec2.h b/generator_cgo/include/ec2.h deleted file mode 100644 index 32f6a83..0000000 --- a/generator_cgo/include/ec2.h +++ /dev/null @@ -1,146 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox UK Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL C++ Header file ec2.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class EC2 (Arithmetic on an Elliptic Curve, - * over GF(2^m) - * - * NOTE : Must be used in conjunction with ec2.cpp and big.cpp - * The active curve is set dynamically (via the Big ecurve2() - * routine) - so beware the pitfalls implicit in declaring - * static or global EC2's (which are initialised before the - * curve is set!). Uninitialised data is OK - */ - -#ifndef EC2_H -#define EC2_H - -#include -#include "big.h" - -#ifdef GF2MS -#define MR_INIT_EC2 memset(mem,0,mr_ecp_reserve(1,GF2MS)); p=(epoint *)epoint_init_mem_variable(mem,0,GF2MS); -#else -#define MR_INIT_EC2 mem=(char *)ecp_memalloc(1); p=(epoint *)epoint_init_mem(mem,0); -#endif - -class EC2 -{ - epoint *p; -#ifdef GF2MS - char mem[mr_ecp_reserve(1,GF2MS)]; -#else - char *mem; -#endif - -public: - EC2() { MR_INIT_EC2} - - EC2(const Big &x,const Big& y) {MR_INIT_EC2 - epoint2_set(x.getbig(),y.getbig(),0,p); } - - // This next constructor restores a point on the curve from "compressed" - // data, that is the full x co-ordinate, and the LSB of y/x (0 or 1) - - EC2(const Big& x,int cb) {MR_INIT_EC2 - epoint2_set(x.getbig(),x.getbig(),cb,p); } - - EC2(const EC2 &b) {MR_INIT_EC2 epoint2_copy(b.p,p);} - - epoint *get_point() const; - - EC2& operator=(const EC2& b) {epoint2_copy(b.p,p);return *this;} - - EC2& operator+=(const EC2& b) {ecurve2_add(b.p,p); return *this;} - EC2& operator-=(const EC2& b) {ecurve2_sub(b.p,p); return *this;} - - // Multiplication of a point by an integer. - - EC2& operator*=(const Big& k) {ecurve2_mult(k.getbig(),p,p); return *this;} - big add(const EC2& b) {return ecurve2_add(b.p,p); } - // returns line slope as a big - big sub(const EC2& b) {return ecurve2_sub(b.p,p); } - - void clear() {epoint2_set(NULL,NULL,0,p);} - BOOL set(const Big& x,const Big& y) {return epoint2_set(x.getbig(),y.getbig(),0,p);} - int get(Big& x,Big& y) const; - BOOL iszero() const; - // This gets the point in compressed form. Return value is LSB of y-coordinate - int get(Big& x) const; - - void getx(Big &x) const; - void getxy(Big &x,Big& y) const; - void getxyz(Big &x,Big &y,Big& z) const; - - // point compression - - // This sets the point from compressed form. cb is LSB of y/x - - BOOL set(const Big& x,int cb=0) {return epoint2_set(x.getbig(),x.getbig(),cb,p);} - - friend EC2 operator-(const EC2&); - friend void multi_add(int,EC2 *,EC2 *); - - friend EC2 mul(const Big&, const EC2&, const Big&, const EC2&); - friend EC2 mul(int, const Big *, EC2 *); - - friend void normalise(EC2 &e) {epoint2_norm(e.p);} - - friend BOOL operator==(const EC2& a,const EC2& b) - {return epoint2_comp(a.p,b.p);} - friend BOOL operator!=(const EC2& a,const EC2& b) - {return (!epoint2_comp(a.p,b.p));} - - friend EC2 operator*(const Big &,const EC2&); - -#ifndef MR_NO_STANDARD_IO - - friend ostream& operator<<(ostream&,const EC2&); - -#endif - - ~EC2() - { -#ifndef GF2MS - mr_free(mem); -#endif - } -}; - -#endif - diff --git a/generator_cgo/include/ecn.h b/generator_cgo/include/ecn.h deleted file mode 100644 index df2f3b0..0000000 --- a/generator_cgo/include/ecn.h +++ /dev/null @@ -1,159 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox UK Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * - * MIRACL C++ Header file ecn.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class ECn (Arithmetic on an Elliptic Curve, - * mod n) - * - * NOTE : Must be used in conjunction with ecn.cpp and big.cpp - * The active curve is set dynamically (via the Big ecurve() - * routine) - so beware the pitfalls implicit in declaring - * static or global ECn's (which are initialised before the - * curve is set!). Uninitialised data is OK - * - */ - -#ifndef ECN_H -#define ECN_H - -#include -#include "big.h" - -#ifdef ZZNS -#define MR_INIT_ECN memset(mem,0,mr_ecp_reserve(1,ZZNS)); p=(epoint *)epoint_init_mem_variable(mem,0,ZZNS); -#else -#define MR_INIT_ECN mem=(char *)ecp_memalloc(1); p=(epoint *)epoint_init_mem(mem,0); -#endif - -class ECn -{ - epoint *p; -#ifdef ZZNS - char mem[mr_ecp_reserve(1,ZZNS)]; -#else - char *mem; -#endif -public: - ECn() {MR_INIT_ECN } - - ECn(const Big &x,const Big& y) {MR_INIT_ECN - epoint_set(x.getbig(),y.getbig(),0,p); } - - // This next constructor restores a point on the curve from "compressed" - // data, that is the full x co-ordinate, and the LSB of y (0 or 1) - -#ifndef MR_SUPPORT_COMPRESSION - ECn(const Big& x,int cb) {MR_INIT_ECN - epoint_set(x.getbig(),x.getbig(),cb,p); } -#endif - - ECn(const ECn &b) {MR_INIT_ECN epoint_copy(b.p,p);} - - epoint *get_point() const; - int get_status() {return p->marker;} - ECn& operator=(const ECn& b) {epoint_copy(b.p,p);return *this;} - - ECn& operator+=(const ECn& b) {ecurve_add(b.p,p); return *this;} - - int add(const ECn&,big *,big *ex1=NULL,big *ex2=NULL) const; - // returns line slope as a big - int sub(const ECn&,big *,big *ex1=NULL,big *ex2=NULL) const; - - ECn& operator-=(const ECn& b) {ecurve_sub(b.p,p); return *this;} - - // Multiplication of a point by an integer. - - ECn& operator*=(const Big& k) {ecurve_mult(k.getbig(),p,p); return *this;} - - void clear() {epoint_set(NULL,NULL,0,p);} - BOOL set(const Big& x,const Big& y) {return epoint_set(x.getbig(),y.getbig(),0,p);} -#ifndef MR_AFFINE_ONLY -// use with care if at all - void setz(const Big& z) {nres(z.getbig(),p->Z); p->marker=MR_EPOINT_GENERAL;} -#endif - BOOL iszero() const; - int get(Big& x,Big& y) const; - - // This gets the point in compressed form. Return value is LSB of y-coordinate - int get(Big& x) const; - - // get raw coordinates - void getx(Big &x) const; - void getxy(Big &x,Big &y) const; - void getxyz(Big &x,Big &y,Big &z) const; - - // point compression - - // This sets the point from compressed form. cb is LSB of y coordinate -#ifndef MR_SUPPORT_COMPRESSION - BOOL set(const Big& x,int cb=0) {return epoint_set(x.getbig(),x.getbig(),cb,p);} -#endif - friend ECn operator-(const ECn&); - friend void multi_add(int,ECn *,ECn *); - friend void double_add(ECn&,ECn&,ECn&,ECn&,big&,big&); - - friend ECn mul(const Big&, const ECn&, const Big&, const ECn&); - friend ECn mul(int, const Big *, ECn *); - - friend void normalise(ECn &e) {epoint_norm(e.p);} - friend void multi_norm(int,ECn *); - - friend BOOL operator==(const ECn& a,const ECn& b) - {return epoint_comp(a.p,b.p);} - friend BOOL operator!=(const ECn& a,const ECn& b) - {return (!epoint_comp(a.p,b.p));} - - friend ECn operator*(const Big &,const ECn&); - -#ifndef MR_NO_STANDARD_IO - - friend ostream& operator<<(ostream&,const ECn&); - -#endif - - ~ECn() { -#ifndef ZZNS - mr_free(mem); -#endif - } - -}; - -#endif - diff --git a/generator_cgo/include/ecnzzn.h b/generator_cgo/include/ecnzzn.h deleted file mode 100644 index 4f7a028..0000000 --- a/generator_cgo/include/ecnzzn.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// Utility functions to force an ECn to be created from 2 or 3 ZZn -// And to extract an ECn into ZZns -// - -#ifndef ECNZZN_H -#define ECNZZN_H - -#include "zzn.h" -#include "ecn.h" - -#ifndef MR_AFFINE_ONLY - -extern void force(ZZn&,ZZn&,ZZn&,ECn&); -extern void extract(ECn&,ZZn&,ZZn&,ZZn&); - -#endif - -extern void force(ZZn&,ZZn&,ECn&); -extern void extract(ECn&,ZZn&,ZZn&); - -#endif diff --git a/generator_cgo/include/ecurve.cpp b/generator_cgo/include/ecurve.cpp deleted file mode 100644 index 5f3b5c6..0000000 --- a/generator_cgo/include/ecurve.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "ecurve.h" -#include - -// 使用的椭圆曲线(SECP256K1)公开参数 -char Q[] = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"; // 有限域的模q -char A[] = "0000000000000000000000000000000000000000000000000000000000000000"; // 曲线方程系数a -char B[] = "0000000000000000000000000000000000000000000000000000000000000007"; // 曲线方程系数b -char X[] = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"; // 基点P的x坐标 -char Y[] = "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"; // 基点P的y坐标 -char P_N[] = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"; // 基点P的阶:令nP=O的最小整数 - -bool setupEcurve(ECC_PARAMS *params) -{ - // 初始化变量 - (*params).a = mirvar(0); - (*params).b = mirvar(0); - (*params).q = mirvar(0); - (*params).p = mirvar(0); - (*params).P_x = mirvar(0); - (*params).P_y = mirvar(0); - (*params).P = epoint_init(); - - // 赋值 - cinstr((*params).a, A); - cinstr((*params).b, B); - cinstr((*params).q, Q); - cinstr((*params).p, P_N); - - cinstr((*params).P_x, X); - cinstr((*params).P_y, Y); - - // 椭圆曲线方程初始化 - ecurve_init((*params).a, (*params).b, (*params).q, MR_PROJECTIVE); - - // 设置点坐标(P_x,P_y)为点P,此函数同时能判断P是否在上面初始化成功的椭圆曲线上 - if (!epoint_set((*params).P_x, (*params).P_y, 0, (*params).P)) - { - freeEcurve(params); - return false; - } - - // 判断P是否是阶为p的基点,判断依据:基点乘以阶为无穷远点 - bool bRv = false; - epoint *P_test = epoint_init(); - ecurve_mult((*params).p, (*params).P, P_test); - if (point_at_infinity(P_test)) - { - bRv = true; - } - else - { - freeEcurve(params); - bRv = false; - } - epoint_free(P_test); - - return bRv; -} - -void freeEcurve(ECC_PARAMS *params) -{ - mirkill((*params).a); - mirkill((*params).b); - mirkill((*params).q); - mirkill((*params).p); - mirkill((*params).P_x); - mirkill((*params).P_y); - - epoint_free((*params).P); -} \ No newline at end of file diff --git a/generator_cgo/include/ecurve.h b/generator_cgo/include/ecurve.h deleted file mode 100644 index 76e754c..0000000 --- a/generator_cgo/include/ecurve.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __ECURVE_H__ -#define __ECURVE_H__ - -#include "miracl.h" -#include "mirdef.h" -#include - -typedef struct ecc_params -{ - big a; // 椭圆曲线方程系数a - big b; // 椭圆曲线方程系数b - big q; // 模 - big p; // 阶 - big P_x; // 基点横坐标 - big P_y; // 基点纵坐标 - epoint *P; // 基点 -} ECC_PARAMS; - -bool setupEcurve(ECC_PARAMS *params); - -void freeEcurve(ECC_PARAMS *params); - -#endif // ecurve.h \ No newline at end of file diff --git a/generator_cgo/include/flash.h b/generator_cgo/include/flash.h deleted file mode 100644 index bac7750..0000000 --- a/generator_cgo/include/flash.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * MIRACL C++ Header file flash.h - * - * AUTHOR : N.Coghlan - * Modified by M.Scott - * - * PURPOSE : Definition of class Flash - * - */ - -#ifndef FLASH_H -#define FLASH_H - -#include "big.h" - -#ifdef MR_FLASH - -#ifdef BIGS -#define MR_FINIT_BIG fn=&b; b.w=a; b.len=0; for (int i=0;i=(const Flash& f1, const Flash& f2) - {if (fcomp(f1.fn,f2.fn) >= 0) return TRUE; else return FALSE;} - friend BOOL operator==(const Flash& f1, const Flash& f2) - {if (fcomp(f1.fn,f2.fn) == 0) return TRUE; else return FALSE;} - friend BOOL operator!=(const Flash& f1, const Flash& f2) - {if (fcomp(f1.fn,f2.fn) != 0) return TRUE; else return FALSE;} - friend BOOL operator<(const Flash& f1, const Flash& f2) - {if (fcomp(f1.fn,f2.fn) < 0) return TRUE; else return FALSE;} - friend BOOL operator>(const Flash& f1, const Flash& f2) - {if (fcomp(f1.fn,f2.fn) > 0) return TRUE; else return FALSE;} - - friend Flash inverse(const Flash&); - friend Flash pi(void); - friend Flash cos(const Flash&); - friend Flash sin(const Flash&); - friend Flash tan(const Flash&); - - friend Flash acos(const Flash&); - friend Flash asin(const Flash&); - friend Flash atan(const Flash&); - - friend Flash cosh(const Flash&); - friend Flash sinh(const Flash&); - friend Flash tanh(const Flash&); - - friend Flash acosh(const Flash&); - friend Flash asinh(const Flash&); - friend Flash atanh(const Flash&); - - friend Flash log(const Flash&); - friend Flash exp(const Flash&); - friend Flash pow(const Flash&,const Flash&); - friend Flash sqrt(const Flash&); - friend Flash nroot(const Flash&,int); - friend Flash fabs(const Flash&); - - friend double todouble(const Flash& f) { return fdsize(f.fn);} - -#ifndef MR_NO_STANDARD_IO - - friend istream& operator>>(istream&, Flash&); - friend ostream& operator<<(ostream&, const Flash&); - -#endif - - -#ifdef BIGS - ~Flash() { } -#else - ~Flash() {mirkill(fn);} -#endif -}; - -extern Flash pi(void); - -#endif -#endif - diff --git a/generator_cgo/include/floating.h b/generator_cgo/include/floating.h deleted file mode 100644 index 5ab7c5f..0000000 --- a/generator_cgo/include/floating.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * MIRACL C++ Header file float.h - * - * AUTHOR : M.Scott - * - * PURPOSE : Definition of class Float - * - */ - -#ifndef FLOAT_H -#define FLOAT_H - -#include -#include "big.h" - -extern void setprecision(int); - -class Float -{ - int e; // exponent - Big m; // mantissa -public: - Float() { } - Float(int i) {m=i; e=1;} - Float(const Float& f) {e=f.e; m=f.m; } - Float(const Big &b) {m=b; e=length(b);} - Float(const Big &b,int ex) {m=b; e=ex;} - Float(double); - - Big trunc(Float *rem=NULL); - void negate() const; - BOOL iszero() const; - BOOL isone() const; - int sign() const; - Float& operator=(double); - BOOL add(const Float&); - Float& operator+=(const Float&); - BOOL sub(const Float&); - Float& operator-=(const Float&); - Float& operator*=(const Float&); - Float& operator*=(int); - Float& operator/=(const Float&); - Float& operator/=(int); - Float& operator=(const Float&); - - friend Float reciprocal(const Float&); - friend double todouble(const Float&); - friend Float makefloat(int,int); - friend Float operator-(const Float&); - friend Float operator+(const Float&,const Float&); - friend Float operator-(const Float&,const Float&); - friend Float operator*(const Float&,const Float&); - friend Float operator*(const Float&,int); - friend Float operator*(int,const Float&); - friend Float operator/(const Float&,const Float&); - friend Float operator/(const Float&,int); - friend Float sqrt(const Float&); - friend Float nroot(const Float&,int); - friend Float exp(const Float&); - friend Float sin(const Float&); - friend Float cos(const Float&); - friend Float pow(const Float&,int); - friend Float fpi(void); - - friend Big trunc(const Float&); - friend int norm(int,Float&); - friend Float fabs(const Float&); - - /* relational ops */ - friend int fcomp(const Float&,const Float&); - - friend BOOL operator<=(const Float& f1, const Float& f2) - {if (fcomp(f1,f2) <= 0) return TRUE; else return FALSE;} - friend BOOL operator>=(const Float& f1, const Float& f2) - {if (fcomp(f1,f2) >= 0) return TRUE; else return FALSE;} - friend BOOL operator==(const Float& f1, const Float& f2) - {if (fcomp(f1,f2) == 0) return TRUE; else return FALSE;} - friend BOOL operator!=(const Float& f1, const Float& f2) - {if (fcomp(f1,f2) != 0) return TRUE; else return FALSE;} - friend BOOL operator<(const Float& f1, const Float& f2) - {if (fcomp(f1,f2) < 0) return TRUE; else return FALSE;} - friend BOOL operator>(const Float& f1, const Float& f2) - {if (fcomp(f1,f2) > 0) return TRUE; else return FALSE;} - - friend ostream& operator<<(ostream&,const Float&); - - ~Float() { } -}; - -extern Float fpi(void); -extern Float makefloat(int,int); - -#endif - diff --git a/generator_cgo/include/gf2m.h b/generator_cgo/include/gf2m.h deleted file mode 100644 index cd95f65..0000000 --- a/generator_cgo/include/gf2m.h +++ /dev/null @@ -1,171 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox UK Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * MIRACL C++ Header file gf2m.h - * - * AUTHOR : M.Scott - * - * PURPOSE : Definition of class GF2m (Arithmetic in the field GF(2^m) - * - * NOTE: : The field basis is set dynamically via the modulo() routine. - * Must be used with big.h and big.cpp - */ - -#ifndef GF2M_H -#define GF2M_H - -#include "big.h" - -/* -#ifdef GF2MS -#define MR_INIT_GF2M memset(mem,0,mr_big_reserve(1,GF2MS)); fn=(big)mirvar_mem_variable(mem,0,GF2MS); -#define MR_CLONE_GF2M(x) fn->len=x->len; for (int i=0;iw[i]=x->w[i]; -#define MR_ZERO_GF2M {fn->len=0; for (int i=0;iw[i]=0;} -#else -#define MR_INIT_GF2M mem=(char *)memalloc(1); fn=(big)mirvar_mem(mem,0); -#define MR_CLONE_GF2M(x) copy(x,fn); -#define MR_ZERO_GF2M zero(fn); -#endif -*/ - - -#ifdef GF2MS -#define MR_INIT_GF2M fn=&b; b.w=a; b.len=GF2MS; -#define MR_CLONE_GF2M(x) b.len=x->len; for (int i=0;iw[i]; -#define MR_ZERO_GF2M {b.len=0; for (int i=0;i GF2m */ - GF2m(big& c) {MR_INIT_GF2M MR_CLONE_GF2M(c)} - GF2m(const GF2m& c) {MR_INIT_GF2M MR_CLONE_GF2M(c.fn)} - GF2m(char *s) {MR_INIT_GF2M cinstr(fn,s); reduce2(fn,fn);} - - GF2m& operator=(const GF2m& c) {MR_CLONE_GF2M(c.fn) return *this;} - GF2m& operator=(big c) {MR_CLONE_GF2M(c) return *this;} - - GF2m& operator=(int i) {if (i==0) MR_ZERO_GF2M else {convert(i,fn); reduce2(fn,fn);} return *this;} - GF2m& operator=(const Big& b) { reduce2(b.getbig(),fn); return *this; } - GF2m& operator=(char *s) { cinstr(fn,s); reduce2(fn,fn); return *this;} - GF2m& operator++() {incr2(fn,1,fn); return *this; } - - GF2m& operator+=(const GF2m& c) - { -#ifdef GF2MS - for (int i=0;iw[i]^=c.fn->w[i]; - fn->len=GF2MS; - if (fn->w[GF2MS-1]==0) mr_lzero(fn); -#else - add2(fn,c.fn,fn); -#endif - return *this; - } - - GF2m& operator+=(int i) {incr2(fn,i,fn); return *this; } - GF2m& operator*=(const GF2m& b) {modmult2(fn,b.fn,fn); return *this;} - GF2m& square() {modsquare2(fn,fn); return *this;} - GF2m& inverse() {inverse2(fn,fn); return *this;} - BOOL quadratic(GF2m& b) {return quad2(fn,b.fn);} - int degree() {return degree2(fn);} - - BOOL iszero() const; - BOOL isone() const; - operator Big() {return (Big)fn;} /* GF2m -> Big */ - friend big getbig(GF2m& z) {return z.fn;} - friend int trace(GF2m & z) {return trace2(z.fn);} - - GF2m& operator/=(const GF2m&); - - friend GF2m operator+(const GF2m&,const GF2m&); - friend GF2m operator+(const GF2m&,int); - friend GF2m operator*(const GF2m&,const GF2m&); - friend GF2m operator/(const GF2m&,const GF2m&); - - friend BOOL operator==(const GF2m& b1,const GF2m& b2) - { if (mr_compare(b1.fn,b2.fn)==0) return TRUE; else return FALSE;} - friend BOOL operator!=(const GF2m& b1,const GF2m& b2) - { if (mr_compare(b1.fn,b2.fn)!=0) return TRUE; else return FALSE;} - - friend GF2m square(const GF2m&); - friend GF2m inverse(const GF2m&); - friend GF2m pow(const GF2m&,int); - friend GF2m sqrt(const GF2m&); - friend GF2m halftrace(const GF2m&); - friend GF2m quad(const GF2m&); -#ifndef MR_NO_RAND - friend GF2m random2(void); -#endif - friend GF2m gcd(const GF2m&,const GF2m&); - - friend void kar2x2(const GF2m*,const GF2m*,GF2m*); - friend void kar3x3(const GF2m*,const GF2m*,GF2m*); - - friend int degree(const GF2m& x) {return degree2(x.fn);} - - ~GF2m() - { - // zero(fn); -#ifndef GF2MS - mr_free(fn); -#endif - } -}; -#ifndef MR_NO_RAND -extern GF2m random2(void); -#endif -#endif diff --git a/generator_cgo/include/hash.h b/generator_cgo/include/hash.h deleted file mode 100644 index 5f96cab..0000000 --- a/generator_cgo/include/hash.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __HASH_H__ -#define __HASH_H__ - -#include "miracl.h" -#include "mirdef.h" - -//hash1(ID, Q, PK_pub, h_1_big) -void hash1(char *ID, epoint *Q, epoint *PK_pub, big p, big h_1_big); - -//hash2(ID, X, h_2_big) -void hash2(char *ID, epoint *X, big p, big h_2_big); - -//hash3(ID, msg, Q, U, PK_pub, h_3_big) -void hash3( - char *ID, - char *msg, - epoint *Q, - epoint *U, - epoint *PK_pub, - big p, - big h_3_big -); - -#endif \ No newline at end of file diff --git a/generator_cgo/include/kgc.h b/generator_cgo/include/kgc.h deleted file mode 100644 index f848b19..0000000 --- a/generator_cgo/include/kgc.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __KGC_H__ -#define __KGC_H__ - -#include "ecurve.h" -#include "miracl.h" -#include "mirdef.h" -#include - - -void genKGCkey(ECC_PARAMS *params, big msk, epoint *PK_pub); - -_Bool genPPK_std( - ECC_PARAMS *params, - big msk, - epoint *PK_pub, - char ID[], - big d, - epoint *Q, - epoint *X -); - -#endif \ No newline at end of file diff --git a/generator_cgo/include/miracl.h b/generator_cgo/include/miracl.h deleted file mode 100644 index 558d19c..0000000 --- a/generator_cgo/include/miracl.h +++ /dev/null @@ -1,1563 +0,0 @@ -/*************************************************************************** - * -Copyright 2013 CertiVox UK Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ - -#ifndef MIRACL_H -#define MIRACL_H - -/* - * main MIRACL header - miracl.h. - */ - -#include "mirdef.h" - -/* Some modifiable defaults... */ - -/* Use a smaller buffer if space is limited, don't be so wasteful! */ - -#ifdef MR_STATIC -#define MR_DEFAULT_BUFFER_SIZE 260 -#else -#define MR_DEFAULT_BUFFER_SIZE 1024 -#endif - -/* see mrgf2m.c */ - -#ifndef MR_KARATSUBA -#define MR_KARATSUBA 2 -#endif - -#ifndef MR_DOUBLE_BIG - -#ifdef MR_KCM - #ifdef MR_FLASH - #define MR_SPACES 32 - #else - #define MR_SPACES 31 - #endif -#else - #ifdef MR_FLASH - #define MR_SPACES 28 - #else - #define MR_SPACES 27 - #endif -#endif - -#else - -#ifdef MR_KCM - #ifdef MR_FLASH - #define MR_SPACES 44 - #else - #define MR_SPACES 43 - #endif -#else - #ifdef MR_FLASH - #define MR_SPACES 40 - #else - #define MR_SPACES 39 - #endif -#endif - -#endif - -/* To avoid name clashes - undefine this */ - -/* #define compare mr_compare */ - -#ifdef MR_AVR -#include -#endif - -/* size of bigs and elliptic curve points for memory allocation from stack or heap */ - -#define MR_ROUNDUP(a,b) ((a)-1)/(b)+1 - -#define MR_SL sizeof(long) - -#ifdef MR_STATIC - -#define MR_SIZE (((sizeof(struct bigtype)+(MR_STATIC+2)*sizeof(mr_utype))-1)/MR_SL+1)*MR_SL -#define MR_BIG_RESERVE(n) ((n)*MR_SIZE+MR_SL) - -#ifdef MR_AFFINE_ONLY -#define MR_ESIZE (((sizeof(epoint)+MR_BIG_RESERVE(2))-1)/MR_SL+1)*MR_SL -#else -#define MR_ESIZE (((sizeof(epoint)+MR_BIG_RESERVE(3))-1)/MR_SL+1)*MR_SL -#endif -#define MR_ECP_RESERVE(n) ((n)*MR_ESIZE+MR_SL) - -#define MR_ESIZE_A (((sizeof(epoint)+MR_BIG_RESERVE(2))-1)/MR_SL+1)*MR_SL -#define MR_ECP_RESERVE_A(n) ((n)*MR_ESIZE_A+MR_SL) - - -#endif - -/* useful macro to convert size of big in words, to size of required structure */ - -#define mr_size(n) (((sizeof(struct bigtype)+((n)+2)*sizeof(mr_utype))-1)/MR_SL+1)*MR_SL -#define mr_big_reserve(n,m) ((n)*mr_size(m)+MR_SL) - -#define mr_esize_a(n) (((sizeof(epoint)+mr_big_reserve(2,(n)))-1)/MR_SL+1)*MR_SL -#define mr_ecp_reserve_a(n,m) ((n)*mr_esize_a(m)+MR_SL) - -#ifdef MR_AFFINE_ONLY -#define mr_esize(n) (((sizeof(epoint)+mr_big_reserve(2,(n)))-1)/MR_SL+1)*MR_SL -#else -#define mr_esize(n) (((sizeof(epoint)+mr_big_reserve(3,(n)))-1)/MR_SL+1)*MR_SL -#endif -#define mr_ecp_reserve(n,m) ((n)*mr_esize(m)+MR_SL) - - -/* if basic library is static, make sure and use static C++ */ - -#ifdef MR_STATIC - #ifndef BIGS - #define BIGS MR_STATIC - #endif - #ifndef ZZNS - #define ZZNS MR_STATIC - #endif - #ifndef GF2MS - #define GF2MS MR_STATIC - #endif -#endif - -#ifdef __ia64__ -#if MIRACL==64 -#define MR_ITANIUM -#include -#endif -#endif - -#ifdef _M_X64 -#ifdef _WIN64 -#if MIRACL==64 -#define MR_WIN64 -#include -#endif -#endif -#endif - -#ifndef MR_NO_FILE_IO -#include -#endif - /* error returns */ - -#define MR_ERR_BASE_TOO_BIG 1 -#define MR_ERR_DIV_BY_ZERO 2 -#define MR_ERR_OVERFLOW 3 -#define MR_ERR_NEG_RESULT 4 -#define MR_ERR_BAD_FORMAT 5 -#define MR_ERR_BAD_BASE 6 -#define MR_ERR_BAD_PARAMETERS 7 -#define MR_ERR_OUT_OF_MEMORY 8 -#define MR_ERR_NEG_ROOT 9 -#define MR_ERR_NEG_POWER 10 -#define MR_ERR_BAD_ROOT 11 -#define MR_ERR_INT_OP 12 -#define MR_ERR_FLASH_OVERFLOW 13 -#define MR_ERR_TOO_BIG 14 -#define MR_ERR_NEG_LOG 15 -#define MR_ERR_DOUBLE_FAIL 16 -#define MR_ERR_IO_OVERFLOW 17 -#define MR_ERR_NO_MIRSYS 18 -#define MR_ERR_BAD_MODULUS 19 -#define MR_ERR_NO_MODULUS 20 -#define MR_ERR_EXP_TOO_BIG 21 -#define MR_ERR_NOT_SUPPORTED 22 -#define MR_ERR_NOT_DOUBLE_LEN 23 -#define MR_ERR_NOT_IRREDUC 24 -#define MR_ERR_NO_ROUNDING 25 -#define MR_ERR_NOT_BINARY 26 -#define MR_ERR_NO_BASIS 27 -#define MR_ERR_COMPOSITE_MODULUS 28 -#define MR_ERR_DEV_RANDOM 29 - - /* some useful definitions */ - -#define forever for(;;) - -#define mr_abs(x) ((x)<0? (-(x)) : (x)) - -#ifndef TRUE - #define TRUE 1 -#endif -#ifndef FALSE - #define FALSE 0 -#endif - -#define OFF 0 -#define ON 1 -#define PLUS 1 -#define MINUS (-1) - -#define M1 (MIRACL-1) -#define M2 (MIRACL-2) -#define M3 (MIRACL-3) -#define M4 (MIRACL-4) -#define TOPBIT ((mr_small)1<= MR_IBITS -#define MR_TOOBIG (1<<(MR_IBITS-2)) -#else -#define MR_TOOBIG (1<<(MIRACL-1)) -#endif - -#ifdef MR_FLASH -#define MR_EBITS (8*sizeof(double) - MR_FLASH) - /* no of Bits per double exponent */ -#define MR_BTS 16 -#define MR_MSK 0xFFFF - -#endif - -/* Default Hash function output size in bytes */ -#define MR_HASH_BYTES 32 - -/* Marsaglia & Zaman Random number generator */ -/* constants alternatives */ -#define NK 37 /* 21 */ -#define NJ 24 /* 6 */ -#define NV 14 /* 8 */ - -/* Use smaller values if memory is precious */ - -#ifdef mr_dltype - -#ifdef MR_LITTLE_ENDIAN -#define MR_BOT 0 -#define MR_TOP 1 -#endif -#ifdef MR_BIG_ENDIAN -#define MR_BOT 1 -#define MR_TOP 0 -#endif - -union doubleword -{ - mr_large d; - mr_small h[2]; -}; - -#endif - -/* chinese remainder theorem structures */ - -typedef struct { -big *C; -big *V; -big *M; -int NP; -} big_chinese; - -typedef struct { -mr_utype *C; -mr_utype *V; -mr_utype *M; -int NP; -} small_chinese; - -/* Cryptographically strong pseudo-random number generator */ - -typedef struct { -mr_unsign32 ira[NK]; /* random number... */ -int rndptr; /* ...array & pointer */ -mr_unsign32 borrow; -int pool_ptr; -char pool[MR_HASH_BYTES]; /* random pool */ -} csprng; - -/* secure hash Algorithm structure */ - -typedef struct { -mr_unsign32 length[2]; -mr_unsign32 h[8]; -mr_unsign32 w[80]; -} sha256; - -typedef sha256 sha; - -#ifdef mr_unsign64 - -typedef struct { -mr_unsign64 length[2]; -mr_unsign64 h[8]; -mr_unsign64 w[80]; -} sha512; - -typedef sha512 sha384; - -typedef struct { -mr_unsign64 length; -mr_unsign64 S[5][5]; -int rate,len; -} sha3; - -#endif - -/* Symmetric Encryption algorithm structure */ - -#define MR_ECB 0 -#define MR_CBC 1 -#define MR_CFB1 2 -#define MR_CFB2 3 -#define MR_CFB4 5 -#define MR_PCFB1 10 -#define MR_PCFB2 11 -#define MR_PCFB4 13 -#define MR_OFB1 14 -#define MR_OFB2 15 -#define MR_OFB4 17 -#define MR_OFB8 21 -#define MR_OFB16 29 - -typedef struct { -int Nk,Nr; -int mode; -mr_unsign32 fkey[60]; -mr_unsign32 rkey[60]; -char f[16]; -} aes; - -/* AES-GCM suppport. See mrgcm.c */ - -#define GCM_ACCEPTING_HEADER 0 -#define GCM_ACCEPTING_CIPHER 1 -#define GCM_NOT_ACCEPTING_MORE 2 -#define GCM_FINISHED 3 -#define GCM_ENCRYPTING 0 -#define GCM_DECRYPTING 1 - -typedef struct { -mr_unsign32 table[128][4]; /* 2k bytes */ -MR_BYTE stateX[16]; -MR_BYTE Y_0[16]; -mr_unsign32 counter; -mr_unsign32 lenA[2],lenC[2]; -int status; -aes a; -} gcm; - - /* Elliptic curve point status */ - -#define MR_EPOINT_GENERAL 0 -#define MR_EPOINT_NORMALIZED 1 -#define MR_EPOINT_INFINITY 2 - -#define MR_NOTSET 0 -#define MR_PROJECTIVE 0 -#define MR_AFFINE 1 -#define MR_BEST 2 -#define MR_TWIST 8 - -#define MR_OVER 0 -#define MR_ADD 1 -#define MR_DOUBLE 2 - -/* Twist type */ - -#define MR_QUADRATIC 2 -#define MR_CUBIC_M 0x3A -#define MR_CUBIC_D 0x3B -#define MR_QUARTIC_M 0x4A -#define MR_QUARTIC_D 0x4B -#define MR_SEXTIC_M 0x6A -#define MR_SEXTIC_D 0x6B - - -/* Fractional Sliding Windows for ECC - how much precomputation storage to use ? */ -/* Note that for variable point multiplication there is an optimal value - which can be reduced if space is short. For fixed points its a matter of - how much ROM is available to store precomputed points. - We are storing the k points (P,3P,5P,7P,...,[2k-1].P) */ - -/* These values can be manually tuned for optimal performance... */ - -#ifdef MR_SMALL_EWINDOW -#define MR_ECC_STORE_N 3 /* point store for ecn variable point multiplication */ -#define MR_ECC_STORE_2M 3 /* point store for ec2m variable point multiplication */ -#define MR_ECC_STORE_N2 3 /* point store for ecn2 variable point multiplication */ -#else -#define MR_ECC_STORE_N 8 /* 8/9 is close to optimal for 256 bit exponents */ -#define MR_ECC_STORE_2M 9 -#define MR_ECC_STORE_N2 8 -#endif - -/*#define MR_ECC_STORE_N2_PRECOMP MR_ECC_STORE_N2 */ - /* Might want to make this bigger.. */ - -/* If multi-addition is of m points, and s precomputed values are required, this is max of m*s (=4.10?) */ -#define MR_MAX_M_T_S 64 - -/* Elliptic Curve epoint structure. Uses projective (X,Y,Z) co-ordinates */ - -typedef struct { -int marker; -big X; -big Y; -#ifndef MR_AFFINE_ONLY -big Z; -#endif -} epoint; - - -/* Structure for Comb method for finite * - field exponentiation with precomputation */ - -typedef struct { -#ifdef MR_STATIC - const mr_small *table; -#else - mr_small *table; -#endif - big n; - int window; - int max; -} brick; - -/* Structure for Comb method for elliptic * - curve exponentiation with precomputation */ - -typedef struct { -#ifdef MR_STATIC - const mr_small *table; -#else - mr_small *table; -#endif - big a,b,n; - int window; - int max; -} ebrick; - -typedef struct { -#ifdef MR_STATIC - const mr_small *table; -#else - mr_small *table; -#endif - big a6,a2; - int m,a,b,c; - int window; - int max; -} ebrick2; - -typedef struct -{ - big a; - big b; -} zzn2; - -typedef struct -{ - zzn2 a; - zzn2 b; - BOOL unitary; -} zzn4; - -typedef struct -{ - int marker; - zzn2 x; - zzn2 y; -#ifndef MR_AFFINE_ONLY - zzn2 z; -#endif - -} ecn2; - -typedef struct -{ - big a; - big b; - big c; -} zzn3; - -typedef struct -{ - zzn2 a; - zzn2 b; - zzn2 c; -} zzn6_3x2; - -/* main MIRACL instance structure */ - -/* ------------------------------------------------------------------------*/ - -typedef struct { -mr_small base; /* number base */ -mr_small apbase; /* apparent base */ -int pack; /* packing density */ -int lg2b; /* bits in base */ -mr_small base2; /* 2^mr_lg2b */ -BOOL (*user)(void); /* pointer to user supplied function */ - -int nib; /* length of bigs */ -#ifndef MR_STRIPPED_DOWN -int depth; /* error tracing ..*/ -int trace[MR_MAXDEPTH]; /* .. mechanism */ -#endif -BOOL check; /* overflow check */ -BOOL fout; /* Output to file */ -BOOL fin; /* Input from file */ -BOOL active; - -#ifndef MR_NO_FILE_IO - -FILE *infile; /* Input file */ -FILE *otfile; /* Output file */ - -#endif - - -#ifndef MR_NO_RAND -mr_unsign32 ira[NK]; /* random number... */ -int rndptr; /* ...array & pointer */ -mr_unsign32 borrow; -#endif - - /* Montgomery constants */ -mr_small ndash; -big modulus; -big pR; -BOOL ACTIVE; -BOOL MONTY; - - /* Elliptic Curve details */ -#ifndef MR_NO_SS -BOOL SS; /* True for Super-Singular */ -#endif -#ifndef MR_NOKOBLITZ -BOOL KOBLITZ; /* True for a Koblitz curve */ -#endif -#ifndef MR_AFFINE_ONLY -int coord; -#endif -int Asize,Bsize; - -int M,AA,BB,CC; /* for GF(2^m) curves */ - -/* -mr_small pm,mask; -int e,k,Me,m; for GF(p^m) curves */ - - -#ifndef MR_STATIC - -int logN; /* constants for fast fourier fft multiplication */ -int nprimes,degree; -mr_utype *prime,*cr; -mr_utype *inverse,**roots; -small_chinese chin; -mr_utype const1,const2,const3; -mr_small msw,lsw; -mr_utype **s1,**s2; /* pre-computed tables for polynomial reduction */ -mr_utype **t; /* workspace */ -mr_utype *wa; -mr_utype *wb; -mr_utype *wc; - -#endif - -BOOL same; -BOOL first_one; -BOOL debug; - -big w0; /* workspace bigs */ -big w1,w2,w3,w4; -big w5,w6,w7; -big w8,w9,w10,w11; -big w12,w13,w14,w15; -big sru; -big one; - -#ifdef MR_KCM -big big_ndash; -big ws,wt; -#endif - -big A,B; - -/* User modifiables */ - -#ifndef MR_SIMPLE_IO -int IOBSIZ; /* size of i/o buffer */ -#endif -BOOL ERCON; /* error control */ -int ERNUM; /* last error code */ -int NTRY; /* no. of tries for probablistic primality testing */ -#ifndef MR_SIMPLE_IO -int INPLEN; /* input length */ -#ifndef MR_SIMPLE_BASE -int IOBASE; /* base for input and output */ - -#endif -#endif -#ifdef MR_FLASH -BOOL EXACT; /* exact flag */ -BOOL RPOINT; /* =ON for radix point, =OFF for fractions in output */ -#endif -#ifndef MR_STRIPPED_DOWN -BOOL TRACER; /* turns trace tracker on/off */ -#endif - -#ifdef MR_STATIC -const int *PRIMES; /* small primes array */ -#ifndef MR_SIMPLE_IO -char IOBUFF[MR_DEFAULT_BUFFER_SIZE]; /* i/o buffer */ -#endif -#else -int *PRIMES; /* small primes array */ -#ifndef MR_SIMPLE_IO -char *IOBUFF; /* i/o buffer */ -#endif -#endif - -#ifdef MR_FLASH -int workprec; -int stprec; /* start precision */ - -int RS,RD; -double D; - -double db,n,p; -int a,b,c,d,r,q,oldn,ndig; -mr_small u,v,ku,kv; - -BOOL last,carryon; -flash pi; - -#endif - -#ifdef MR_FP_ROUNDING -mr_large inverse_base; -#endif - -#ifndef MR_STATIC -char *workspace; -#else -char workspace[MR_BIG_RESERVE(MR_SPACES)]; -#endif - -int TWIST; /* set to twisted curve */ -int qnr; /* a QNR -1 for p=3 mod 4, -2 for p=5 mod 8, 0 otherwise */ -int cnr; /* a cubic non-residue */ -int pmod8; -int pmod9; -BOOL NO_CARRY; -} miracl; - -/* ------------------------------------------------------------------------*/ - - -#ifndef MR_GENERIC_MT - -#ifdef MR_WINDOWS_MT -#define MR_OS_THREADS -#endif - -#ifdef MR_UNIX_MT -#define MR_OS_THREADS -#endif - -#ifdef MR_OPENMP_MT -#define MR_OS_THREADS -#endif - - -#ifndef MR_OS_THREADS - -extern miracl *mr_mip; /* pointer to MIRACL's only global variable */ - -#endif - -#endif - -#ifdef MR_GENERIC_MT - -#ifdef MR_STATIC -#define MR_GENERIC_AND_STATIC -#endif - -#define _MIPT_ miracl *, -#define _MIPTO_ miracl * -#define _MIPD_ miracl *mr_mip, -#define _MIPDO_ miracl *mr_mip -#define _MIPP_ mr_mip, -#define _MIPPO_ mr_mip - -#else - -#define _MIPT_ -#define _MIPTO_ void -#define _MIPD_ -#define _MIPDO_ void -#define _MIPP_ -#define _MIPPO_ - -#endif - -/* Preamble and exit code for MIRACL routines. * - * Not used if MR_STRIPPED_DOWN is defined */ - -#ifdef MR_STRIPPED_DOWN -#define MR_OUT -#define MR_IN(N) -#else -#define MR_OUT mr_mip->depth--; -#define MR_IN(N) mr_mip->depth++; if (mr_mip->depthtrace[mr_mip->depth]=(N); if (mr_mip->TRACER) mr_track(_MIPPO_); } -#endif - -/* Function definitions */ - -/* Group 0 - Internal routines */ - -extern void mr_berror(_MIPT_ int); -extern mr_small mr_shiftbits(mr_small,int); -extern mr_small mr_setbase(_MIPT_ mr_small); -extern void mr_track(_MIPTO_ ); -extern void mr_lzero(big); -extern BOOL mr_notint(flash); -extern int mr_lent(flash); -extern void mr_padd(_MIPT_ big,big,big); -extern void mr_psub(_MIPT_ big,big,big); -extern void mr_pmul(_MIPT_ big,mr_small,big); -#ifdef MR_FP_ROUNDING -extern mr_large mr_invert(mr_small); -extern mr_small imuldiv(mr_small,mr_small,mr_small,mr_small,mr_large,mr_small *); -extern mr_small mr_sdiv(_MIPT_ big,mr_small,mr_large,big); -#else -extern mr_small mr_sdiv(_MIPT_ big,mr_small,big); -extern void mr_and(big,big,big); -extern void mr_xor(big,big,big); -#endif -extern void mr_shift(_MIPT_ big,int,big); -extern miracl *mr_first_alloc(void); -extern void *mr_alloc(_MIPT_ int,int); -extern void mr_free(void *); -extern void set_user_function(_MIPT_ BOOL (*)(void)); -extern void set_io_buffer_size(_MIPT_ int); -extern int mr_testbit(_MIPT_ big,int); -extern void mr_addbit(_MIPT_ big,int); -extern int recode(_MIPT_ big ,int ,int ,int ); -extern int mr_window(_MIPT_ big,int,int *,int *,int); -extern int mr_window2(_MIPT_ big,big,int,int *,int *); -extern int mr_naf_window(_MIPT_ big,big,int,int *,int *,int); - -extern int mr_fft_init(_MIPT_ int,big,big,BOOL); -extern void mr_dif_fft(_MIPT_ int,int,mr_utype *); -extern void mr_dit_fft(_MIPT_ int,int,mr_utype *); -extern void fft_reset(_MIPTO_); - -extern int mr_poly_mul(_MIPT_ int,big*,int,big*,big*); -extern int mr_poly_sqr(_MIPT_ int,big*,big*); -extern void mr_polymod_set(_MIPT_ int,big*,big*); -extern int mr_poly_rem(_MIPT_ int,big *,big *); - -extern int mr_ps_big_mul(_MIPT_ int,big *,big *,big *); -extern int mr_ps_zzn_mul(_MIPT_ int,big *,big *,big *); - -extern mr_small muldiv(mr_small,mr_small,mr_small,mr_small,mr_small *); -extern mr_small muldvm(mr_small,mr_small,mr_small,mr_small *); -extern mr_small muldvd(mr_small,mr_small,mr_small,mr_small *); -extern void muldvd2(mr_small,mr_small,mr_small *,mr_small *); - -extern flash mirvar_mem_variable(char *,int,int); -extern epoint* epoint_init_mem_variable(_MIPT_ char *,int,int); - -/* Group 1 - General purpose, I/O and basic arithmetic routines */ - -extern unsigned int igcd(unsigned int,unsigned int); -extern unsigned long lgcd(unsigned long,unsigned long); -extern mr_small sgcd(mr_small,mr_small); -extern unsigned int isqrt(unsigned int,unsigned int); -extern unsigned long mr_lsqrt(unsigned long,unsigned long); -extern void irand(_MIPT_ mr_unsign32); -extern mr_small brand(_MIPTO_ ); -extern void zero(flash); -extern void convert(_MIPT_ int,big); -extern void uconvert(_MIPT_ unsigned int,big); -extern void lgconv(_MIPT_ long,big); -extern void ulgconv(_MIPT_ unsigned long,big); -extern void tconvert(_MIPT_ mr_utype,big); - -#ifdef mr_dltype -extern void dlconv(_MIPT_ mr_dltype,big); -#endif - -extern flash mirvar(_MIPT_ int); -extern flash mirvar_mem(_MIPT_ char *,int); -extern void mirkill(big); -extern void *memalloc(_MIPT_ int); -extern void memkill(_MIPT_ char *,int); -extern void mr_init_threading(void); -extern void mr_end_threading(void); -extern miracl *get_mip(void ); -extern void set_mip(miracl *); -#ifdef MR_GENERIC_AND_STATIC -extern miracl *mirsys(miracl *,int,mr_small); -#else -extern miracl *mirsys(int,mr_small); -#endif -extern miracl *mirsys_basic(miracl *,int,mr_small); -extern void mirexit(_MIPTO_ ); -extern int exsign(flash); -extern void insign(int,flash); -extern int getdig(_MIPT_ big,int); -extern int numdig(_MIPT_ big); -extern void putdig(_MIPT_ int,big,int); -extern void copy(flash,flash); -extern void negify(flash,flash); -extern void absol(flash,flash); -extern int size(big); -extern int mr_compare(big,big); -extern void add(_MIPT_ big,big,big); -extern void subtract(_MIPT_ big,big,big); -extern void incr(_MIPT_ big,int,big); -extern void decr(_MIPT_ big,int,big); -extern void premult(_MIPT_ big,int,big); -extern int subdiv(_MIPT_ big,int,big); -extern BOOL subdivisible(_MIPT_ big,int); -extern int remain(_MIPT_ big,int); -extern void bytes_to_big(_MIPT_ int,const char *,big); -extern int big_to_bytes(_MIPT_ int,big,char *,BOOL); -extern mr_small normalise(_MIPT_ big,big); -extern void multiply(_MIPT_ big,big,big); -extern void fft_mult(_MIPT_ big,big,big); -extern BOOL fastmultop(_MIPT_ int,big,big,big); -extern void divide(_MIPT_ big,big,big); -extern BOOL divisible(_MIPT_ big,big); -extern void mad(_MIPT_ big,big,big,big,big,big); -extern int instr(_MIPT_ flash,char *); -extern int otstr(_MIPT_ flash,char *); -extern int cinstr(_MIPT_ flash,char *); -extern int cotstr(_MIPT_ flash,char *); -extern epoint* epoint_init(_MIPTO_ ); -extern epoint* epoint_init_mem(_MIPT_ char *,int); -extern void* ecp_memalloc(_MIPT_ int); -void ecp_memkill(_MIPT_ char *,int); -BOOL init_big_from_rom(big,int,const mr_small *,int ,int *); -BOOL init_point_from_rom(epoint *,int,const mr_small *,int,int *); - -#ifndef MR_NO_FILE_IO - -extern int innum(_MIPT_ flash,FILE *); -extern int otnum(_MIPT_ flash,FILE *); -extern int cinnum(_MIPT_ flash,FILE *); -extern int cotnum(_MIPT_ flash,FILE *); - -#endif - -/* Group 2 - Advanced arithmetic routines */ - -extern mr_small smul(mr_small,mr_small,mr_small); -extern mr_small spmd(mr_small,mr_small,mr_small); -extern mr_small invers(mr_small,mr_small); -extern mr_small sqrmp(mr_small,mr_small); -extern int jac(mr_small,mr_small); - -extern void gprime(_MIPT_ int); -extern int jack(_MIPT_ big,big); -extern int egcd(_MIPT_ big,big,big); -extern int xgcd(_MIPT_ big,big,big,big,big); -extern int invmodp(_MIPT_ big,big,big); -extern int logb2(_MIPT_ big); -extern int hamming(_MIPT_ big); -extern void expb2(_MIPT_ int,big); -extern void bigbits(_MIPT_ int,big); -extern void expint(_MIPT_ int,int,big); -extern void sftbit(_MIPT_ big,int,big); -extern void power(_MIPT_ big,long,big,big); -extern void powmod(_MIPT_ big,big,big,big); -extern void powmod2(_MIPT_ big,big,big,big,big,big); -extern void powmodn(_MIPT_ int,big *,big *,big,big); -extern int powltr(_MIPT_ int,big,big,big); -extern BOOL double_inverse(_MIPT_ big,big,big,big,big); -extern BOOL multi_inverse(_MIPT_ int,big*,big,big*); -extern void lucas(_MIPT_ big,big,big,big,big); -extern BOOL nroot(_MIPT_ big,int,big); -extern BOOL sqroot(_MIPT_ big,big,big); -extern void bigrand(_MIPT_ big,big); -extern void bigdig(_MIPT_ int,int,big); -extern int trial_division(_MIPT_ big,big); -extern BOOL isprime(_MIPT_ big); -extern BOOL nxprime(_MIPT_ big,big); -extern BOOL nxsafeprime(_MIPT_ int,int,big,big); -extern BOOL crt_init(_MIPT_ big_chinese *,int,big *); -extern void crt(_MIPT_ big_chinese *,big *,big); -extern void crt_end(big_chinese *); -extern BOOL scrt_init(_MIPT_ small_chinese *,int,mr_utype *); -extern void scrt(_MIPT_ small_chinese*,mr_utype *,big); -extern void scrt_end(small_chinese *); -#ifndef MR_STATIC -extern BOOL brick_init(_MIPT_ brick *,big,big,int,int); -extern void brick_end(brick *); -#else -extern void brick_init(brick *,const mr_small *,big,int,int); -#endif -extern void pow_brick(_MIPT_ brick *,big,big); -#ifndef MR_STATIC -extern BOOL ebrick_init(_MIPT_ ebrick *,big,big,big,big,big,int,int); -extern void ebrick_end(ebrick *); -#else -extern void ebrick_init(ebrick *,const mr_small *,big,big,big,int,int); -#endif -extern int mul_brick(_MIPT_ ebrick*,big,big,big); -#ifndef MR_STATIC -extern BOOL ebrick2_init(_MIPT_ ebrick2 *,big,big,big,big,int,int,int,int,int,int); -extern void ebrick2_end(ebrick2 *); -#else -extern void ebrick2_init(ebrick2 *,const mr_small *,big,big,int,int,int,int,int,int); -#endif -extern int mul2_brick(_MIPT_ ebrick2*,big,big,big); - -/* Montgomery stuff */ - -extern mr_small prepare_monty(_MIPT_ big); -extern void kill_monty(_MIPTO_ ); -extern void nres(_MIPT_ big,big); -extern void redc(_MIPT_ big,big); - -extern void nres_negate(_MIPT_ big,big); -extern void nres_modadd(_MIPT_ big,big,big); -extern void nres_modsub(_MIPT_ big,big,big); -extern void nres_lazy(_MIPT_ big,big,big,big,big,big); -extern void nres_complex(_MIPT_ big,big,big,big); -extern void nres_double_modadd(_MIPT_ big,big,big); -extern void nres_double_modsub(_MIPT_ big,big,big); -extern void nres_premult(_MIPT_ big,int,big); -extern void nres_modmult(_MIPT_ big,big,big); -extern int nres_moddiv(_MIPT_ big,big,big); -extern void nres_dotprod(_MIPT_ int,big *,big *,big); -extern void nres_powmod(_MIPT_ big,big,big); -extern void nres_powltr(_MIPT_ int,big,big); -extern void nres_powmod2(_MIPT_ big,big,big,big,big); -extern void nres_powmodn(_MIPT_ int,big *,big *,big); -extern BOOL nres_sqroot(_MIPT_ big,big); -extern void nres_lucas(_MIPT_ big,big,big,big); -extern BOOL nres_double_inverse(_MIPT_ big,big,big,big); -extern BOOL nres_multi_inverse(_MIPT_ int,big *,big *); -extern void nres_div2(_MIPT_ big,big); -extern void nres_div3(_MIPT_ big,big); -extern void nres_div5(_MIPT_ big,big); - -extern void shs_init(sha *); -extern void shs_process(sha *,int); -extern void shs_hash(sha *,char *); - -extern void shs256_init(sha256 *); -extern void shs256_process(sha256 *,int); -extern void shs256_hash(sha256 *,char *); - -#ifdef mr_unsign64 - -extern void shs512_init(sha512 *); -extern void shs512_process(sha512 *,int); -extern void shs512_hash(sha512 *,char *); - -extern void shs384_init(sha384 *); -extern void shs384_process(sha384 *,int); -extern void shs384_hash(sha384 *,char *); - -extern void sha3_init(sha3 *,int); -extern void sha3_process(sha3 *,int); -extern void sha3_hash(sha3 *,char *); - -#endif - -extern BOOL aes_init(aes *,int,int,char *,char *); -extern void aes_getreg(aes *,char *); -extern void aes_ecb_encrypt(aes *,MR_BYTE *); -extern void aes_ecb_decrypt(aes *,MR_BYTE *); -extern mr_unsign32 aes_encrypt(aes *,char *); -extern mr_unsign32 aes_decrypt(aes *,char *); -extern void aes_reset(aes *,int,char *); -extern void aes_end(aes *); - -extern void gcm_init(gcm *,int,char *,int,char *); -extern BOOL gcm_add_header(gcm *,char *,int); -extern BOOL gcm_add_cipher(gcm *,int,char *,int,char *); -extern void gcm_finish(gcm *,char *); - -extern void FPE_encrypt(int ,aes *,mr_unsign32 ,mr_unsign32 ,char *,int); -extern void FPE_decrypt(int ,aes *,mr_unsign32 ,mr_unsign32 ,char *,int); - -extern void strong_init(csprng *,int,char *,mr_unsign32); -extern int strong_rng(csprng *); -extern void strong_bigrand(_MIPT_ csprng *,big,big); -extern void strong_bigdig(_MIPT_ csprng *,int,int,big); -extern void strong_kill(csprng *); - -/* special modular multipliers */ - -extern void comba_mult(big,big,big); -extern void comba_square(big,big); -extern void comba_redc(_MIPT_ big,big); -extern void comba_modadd(_MIPT_ big,big,big); -extern void comba_modsub(_MIPT_ big,big,big); -extern void comba_double_modadd(_MIPT_ big,big,big); -extern void comba_double_modsub(_MIPT_ big,big,big); -extern void comba_negate(_MIPT_ big,big); -extern void comba_add(big,big,big); -extern void comba_sub(big,big,big); -extern void comba_double_add(big,big,big); -extern void comba_double_sub(big,big,big); - -extern void comba_mult2(_MIPT_ big,big,big); - -extern void fastmodmult(_MIPT_ big,big,big); -extern void fastmodsquare(_MIPT_ big,big); - -extern void kcm_mul(_MIPT_ big,big,big); -extern void kcm_sqr(_MIPT_ big,big); -extern void kcm_redc(_MIPT_ big,big); - -extern void kcm_multiply(_MIPT_ int,big,big,big); -extern void kcm_square(_MIPT_ int,big,big); -extern BOOL kcm_top(_MIPT_ int,big,big,big); - -/* elliptic curve stuff */ - -extern BOOL point_at_infinity(epoint *); - -extern void mr_jsf(_MIPT_ big,big,big,big,big,big); - -extern void ecurve_init(_MIPT_ big,big,big,int); -extern int ecurve_add(_MIPT_ epoint *,epoint *); -extern int ecurve_sub(_MIPT_ epoint *,epoint *); -extern void ecurve_double_add(_MIPT_ epoint *,epoint *,epoint *,epoint *,big *,big *); -extern void ecurve_multi_add(_MIPT_ int,epoint **,epoint **); -extern void ecurve_double(_MIPT_ epoint*); -extern int ecurve_mult(_MIPT_ big,epoint *,epoint *); -extern void ecurve_mult2(_MIPT_ big,epoint *,big,epoint *,epoint *); -extern void ecurve_multn(_MIPT_ int,big *,epoint**,epoint *); - -extern BOOL epoint_x(_MIPT_ big); -extern BOOL epoint_set(_MIPT_ big,big,int,epoint*); -extern int epoint_get(_MIPT_ epoint*,big,big); -extern void epoint_getxyz(_MIPT_ epoint *,big,big,big); -extern BOOL epoint_norm(_MIPT_ epoint *); -extern BOOL epoint_multi_norm(_MIPT_ int,big *,epoint **); -extern void epoint_free(epoint *); -extern void epoint_copy(epoint *,epoint *); -extern BOOL epoint_comp(_MIPT_ epoint *,epoint *); -extern void epoint_negate(_MIPT_ epoint *); - -extern BOOL ecurve2_init(_MIPT_ int,int,int,int,big,big,BOOL,int); -extern big ecurve2_add(_MIPT_ epoint *,epoint *); -extern big ecurve2_sub(_MIPT_ epoint *,epoint *); -extern void ecurve2_multi_add(_MIPT_ int,epoint **,epoint **); -extern void ecurve2_mult(_MIPT_ big,epoint *,epoint *); -extern void ecurve2_mult2(_MIPT_ big,epoint *,big,epoint *,epoint *); -extern void ecurve2_multn(_MIPT_ int,big *,epoint**,epoint *); - -extern epoint* epoint2_init(_MIPTO_ ); -extern BOOL epoint2_set(_MIPT_ big,big,int,epoint*); -extern int epoint2_get(_MIPT_ epoint*,big,big); -extern void epoint2_getxyz(_MIPT_ epoint *,big,big,big); -extern int epoint2_norm(_MIPT_ epoint *); -extern void epoint2_free(epoint *); -extern void epoint2_copy(epoint *,epoint *); -extern BOOL epoint2_comp(_MIPT_ epoint *,epoint *); -extern void epoint2_negate(_MIPT_ epoint *); - -/* GF(2) stuff */ - -extern BOOL prepare_basis(_MIPT_ int,int,int,int,BOOL); -extern int parity2(big); -extern BOOL multi_inverse2(_MIPT_ int,big *,big *); -extern void add2(big,big,big); -extern void incr2(big,int,big); -extern void reduce2(_MIPT_ big,big); -extern void multiply2(_MIPT_ big,big,big); -extern void modmult2(_MIPT_ big,big,big); -extern void modsquare2(_MIPT_ big,big); -extern void power2(_MIPT_ big,int,big); -extern void sqroot2(_MIPT_ big,big); -extern void halftrace2(_MIPT_ big,big); -extern BOOL quad2(_MIPT_ big,big); -extern BOOL inverse2(_MIPT_ big,big); -extern void karmul2(int,mr_small *,mr_small *,mr_small *,mr_small *); -extern void karmul2_poly(_MIPT_ int,big *,big *,big *,big *); -extern void karmul2_poly_upper(_MIPT_ int,big *,big *,big *,big *); -extern void gf2m_dotprod(_MIPT_ int,big *,big *,big); -extern int trace2(_MIPT_ big); -extern void rand2(_MIPT_ big); -extern void gcd2(_MIPT_ big,big,big); -extern int degree2(big); - -/* zzn2 stuff */ - -extern BOOL zzn2_iszero(zzn2 *); -extern BOOL zzn2_isunity(_MIPT_ zzn2 *); -extern void zzn2_from_int(_MIPT_ int,zzn2 *); -extern void zzn2_from_ints(_MIPT_ int,int,zzn2 *); -extern void zzn2_copy(zzn2 *,zzn2 *); -extern void zzn2_zero(zzn2 *); -extern void zzn2_negate(_MIPT_ zzn2 *,zzn2 *); -extern void zzn2_conj(_MIPT_ zzn2 *,zzn2 *); -extern void zzn2_add(_MIPT_ zzn2 *,zzn2 *,zzn2 *); -extern void zzn2_sub(_MIPT_ zzn2 *,zzn2 *,zzn2 *); -extern void zzn2_smul(_MIPT_ zzn2 *,big,zzn2 *); -extern void zzn2_mul(_MIPT_ zzn2 *,zzn2 *,zzn2 *); -extern void zzn2_sqr(_MIPT_ zzn2 *,zzn2 *); -extern void zzn2_inv(_MIPT_ zzn2 *); -extern void zzn2_timesi(_MIPT_ zzn2 *); -extern void zzn2_powl(_MIPT_ zzn2 *,big,zzn2 *); -extern void zzn2_from_zzns(big,big,zzn2 *); -extern void zzn2_from_bigs(_MIPT_ big,big,zzn2 *); -extern void zzn2_from_zzn(big,zzn2 *); -extern void zzn2_from_big(_MIPT_ big, zzn2 *); -extern void zzn2_sadd(_MIPT_ zzn2 *,big,zzn2 *); -extern void zzn2_ssub(_MIPT_ zzn2 *,big,zzn2 *); -extern void zzn2_div2(_MIPT_ zzn2 *); -extern void zzn2_div3(_MIPT_ zzn2 *); -extern void zzn2_div5(_MIPT_ zzn2 *); -extern void zzn2_imul(_MIPT_ zzn2 *,int,zzn2 *); -extern BOOL zzn2_compare(zzn2 *,zzn2 *); -extern void zzn2_txx(_MIPT_ zzn2 *); -extern void zzn2_txd(_MIPT_ zzn2 *); -extern BOOL zzn2_sqrt(_MIPT_ zzn2 *,zzn2 *); -extern BOOL zzn2_qr(_MIPT_ zzn2 *); -extern BOOL zzn2_multi_inverse(_MIPT_ int,zzn2 *,zzn2 *); - - -/* zzn3 stuff */ - -extern void zzn3_set(_MIPT_ int,big); -extern BOOL zzn3_iszero(zzn3 *); -extern BOOL zzn3_isunity(_MIPT_ zzn3 *); -extern void zzn3_from_int(_MIPT_ int,zzn3 *); -extern void zzn3_from_ints(_MIPT_ int,int,int,zzn3 *); -extern void zzn3_copy(zzn3 *,zzn3 *); -extern void zzn3_zero(zzn3 *); -extern void zzn3_negate(_MIPT_ zzn3 *,zzn3 *); -extern void zzn3_powq(_MIPT_ zzn3 *,zzn3 *); -extern void zzn3_add(_MIPT_ zzn3 *,zzn3 *,zzn3 *); -extern void zzn3_sub(_MIPT_ zzn3 *,zzn3 *,zzn3 *); -extern void zzn3_smul(_MIPT_ zzn3 *,big,zzn3 *); -extern void zzn3_mul(_MIPT_ zzn3 *,zzn3 *,zzn3 *); -extern void zzn3_inv(_MIPT_ zzn3 *); -extern void zzn3_timesi(_MIPT_ zzn3 *); -extern void zzn3_timesi2(_MIPT_ zzn3 *); -extern void zzn3_powl(_MIPT_ zzn3 *,big,zzn3 *); -extern void zzn3_from_zzns(big,big,big,zzn3 *); -extern void zzn3_from_bigs(_MIPT_ big,big,big,zzn3 *); -extern void zzn3_from_zzn(big,zzn3 *); -extern void zzn3_from_zzn_1(big,zzn3 *); -extern void zzn3_from_zzn_2(big,zzn3 *); -extern void zzn3_from_big(_MIPT_ big, zzn3 *); -extern void zzn3_sadd(_MIPT_ zzn3 *,big,zzn3 *); -extern void zzn3_ssub(_MIPT_ zzn3 *,big,zzn3 *); -extern void zzn3_div2(_MIPT_ zzn3 *); -extern void zzn3_imul(_MIPT_ zzn3 *,int,zzn3 *); -extern BOOL zzn3_compare(zzn3 *,zzn3 *); - -/* zzn4 stuff */ - -extern BOOL zzn4_iszero(zzn4 *); -extern BOOL zzn4_isunity(_MIPT_ zzn4 *); -extern void zzn4_from_int(_MIPT_ int,zzn4 *); -extern void zzn4_copy(zzn4 *,zzn4 *); -extern void zzn4_zero(zzn4 *); -extern void zzn4_negate(_MIPT_ zzn4 *,zzn4 *); -extern void zzn4_powq(_MIPT_ zzn2 *,zzn4 *); -extern void zzn4_add(_MIPT_ zzn4 *,zzn4 *,zzn4 *); -extern void zzn4_sub(_MIPT_ zzn4 *,zzn4 *,zzn4 *); -extern void zzn4_smul(_MIPT_ zzn4 *,zzn2 *,zzn4 *); -extern void zzn4_sqr(_MIPT_ zzn4 *,zzn4 *); -extern void zzn4_mul(_MIPT_ zzn4 *,zzn4 *,zzn4 *); -extern void zzn4_inv(_MIPT_ zzn4 *); -extern void zzn4_timesi(_MIPT_ zzn4 *); -extern void zzn4_tx(_MIPT_ zzn4 *); -extern void zzn4_from_zzn2s(zzn2 *,zzn2 *,zzn4 *); -extern void zzn4_from_zzn2(zzn2 *,zzn4 *); -extern void zzn4_from_zzn2h(zzn2 *,zzn4 *); -extern void zzn4_from_zzn(big,zzn4 *); -extern void zzn4_from_big(_MIPT_ big , zzn4 *); -extern void zzn4_sadd(_MIPT_ zzn4 *,zzn2 *,zzn4 *); -extern void zzn4_ssub(_MIPT_ zzn4 *,zzn2 *,zzn4 *); -extern void zzn4_div2(_MIPT_ zzn4 *); -extern void zzn4_conj(_MIPT_ zzn4 *,zzn4 *); -extern void zzn4_imul(_MIPT_ zzn4 *,int,zzn4 *); -extern void zzn4_lmul(_MIPT_ zzn4 *,big,zzn4 *); -extern BOOL zzn4_compare(zzn4 *,zzn4 *); - -/* ecn2 stuff */ - -extern BOOL ecn2_iszero(ecn2 *); -extern void ecn2_copy(ecn2 *,ecn2 *); -extern void ecn2_zero(ecn2 *); -extern BOOL ecn2_compare(_MIPT_ ecn2 *,ecn2 *); -extern void ecn2_norm(_MIPT_ ecn2 *); -extern void ecn2_get(_MIPT_ ecn2 *,zzn2 *,zzn2 *,zzn2 *); -extern void ecn2_getxy(ecn2 *,zzn2 *,zzn2 *); -extern void ecn2_getx(ecn2 *,zzn2 *); -extern void ecn2_getz(_MIPT_ ecn2 *,zzn2 *); -extern void ecn2_rhs(_MIPT_ zzn2 *,zzn2 *); -extern BOOL ecn2_set(_MIPT_ zzn2 *,zzn2 *,ecn2 *); -extern BOOL ecn2_setx(_MIPT_ zzn2 *,ecn2 *); -extern void ecn2_setxyz(_MIPT_ zzn2 *,zzn2 *,zzn2 *,ecn2 *); -extern void ecn2_negate(_MIPT_ ecn2 *,ecn2 *); -extern BOOL ecn2_add3(_MIPT_ ecn2 *,ecn2 *,zzn2 *,zzn2 *,zzn2 *); -extern BOOL ecn2_add2(_MIPT_ ecn2 *,ecn2 *,zzn2 *,zzn2 *); -extern BOOL ecn2_add1(_MIPT_ ecn2 *,ecn2 *,zzn2 *); -extern BOOL ecn2_add(_MIPT_ ecn2 *,ecn2 *); -extern BOOL ecn2_sub(_MIPT_ ecn2 *,ecn2 *); -extern BOOL ecn2_add_sub(_MIPT_ ecn2 *,ecn2 *,ecn2 *,ecn2 *); -extern int ecn2_mul2_jsf(_MIPT_ big,ecn2 *,big,ecn2 *,ecn2 *); -extern int ecn2_mul(_MIPT_ big,ecn2 *); -extern void ecn2_psi(_MIPT_ zzn2 *,ecn2 *); -extern BOOL ecn2_multi_norm(_MIPT_ int ,zzn2 *,ecn2 *); -extern int ecn2_mul4_gls_v(_MIPT_ big *,int,ecn2 *,big *,ecn2 *,zzn2 *,ecn2 *); -extern int ecn2_muln_engine(_MIPT_ int,int,int,int,big *,big *,big *,big *,ecn2 *,ecn2 *,ecn2 *); -extern void ecn2_precomp_gls(_MIPT_ int,BOOL,ecn2 *,zzn2 *,ecn2 *); -extern int ecn2_mul2_gls(_MIPT_ big *,ecn2 *,zzn2 *,ecn2 *); -extern void ecn2_precomp(_MIPT_ int,BOOL,ecn2 *,ecn2 *); -extern int ecn2_mul2(_MIPT_ big,int,ecn2 *,big,ecn2 *,ecn2 *); -#ifndef MR_STATIC -extern BOOL ecn2_brick_init(_MIPT_ ebrick *,zzn2 *,zzn2 *,big,big,big,int,int); -extern void ecn2_brick_end(ebrick *); -#else -extern void ebrick_init(ebrick *,const mr_small *,big,big,big,int,int); -#endif -extern void ecn2_mul_brick_gls(_MIPT_ ebrick *B,big *,zzn2 *,zzn2 *,zzn2 *); -extern void ecn2_multn(_MIPT_ int,big *,ecn2 *,ecn2 *); -extern void ecn2_mult4(_MIPT_ big *,ecn2 *,ecn2 *); -/* Group 3 - Floating-slash routines */ - -#ifdef MR_FLASH -extern void fpack(_MIPT_ big,big,flash); -extern void numer(_MIPT_ flash,big); -extern void denom(_MIPT_ flash,big); -extern BOOL fit(big,big,int); -extern void build(_MIPT_ flash,int (*)(_MIPT_ big,int)); -extern void mround(_MIPT_ big,big,flash); -extern void flop(_MIPT_ flash,flash,int *,flash); -extern void fmul(_MIPT_ flash,flash,flash); -extern void fdiv(_MIPT_ flash,flash,flash); -extern void fadd(_MIPT_ flash,flash,flash); -extern void fsub(_MIPT_ flash,flash,flash); -extern int fcomp(_MIPT_ flash,flash); -extern void fconv(_MIPT_ int,int,flash); -extern void frecip(_MIPT_ flash,flash); -extern void ftrunc(_MIPT_ flash,big,flash); -extern void fmodulo(_MIPT_ flash,flash,flash); -extern void fpmul(_MIPT_ flash,int,int,flash); -extern void fincr(_MIPT_ flash,int,int,flash); -extern void dconv(_MIPT_ double,flash); -extern double fdsize(_MIPT_ flash); -extern void frand(_MIPT_ flash); - -/* Group 4 - Advanced Flash routines */ - -extern void fpower(_MIPT_ flash,int,flash); -extern BOOL froot(_MIPT_ flash,int,flash); -extern void fpi(_MIPT_ flash); -extern void fexp(_MIPT_ flash,flash); -extern void flog(_MIPT_ flash,flash); -extern void fpowf(_MIPT_ flash,flash,flash); -extern void ftan(_MIPT_ flash,flash); -extern void fatan(_MIPT_ flash,flash); -extern void fsin(_MIPT_ flash,flash); -extern void fasin(_MIPT_ flash,flash); -extern void fcos(_MIPT_ flash,flash); -extern void facos(_MIPT_ flash,flash); -extern void ftanh(_MIPT_ flash,flash); -extern void fatanh(_MIPT_ flash,flash); -extern void fsinh(_MIPT_ flash,flash); -extern void fasinh(_MIPT_ flash,flash); -extern void fcosh(_MIPT_ flash,flash); -extern void facosh(_MIPT_ flash,flash); -#endif - - -/* Test predefined Macros to determine compiler type, and hopefully - selectively use fast in-line assembler (or other compiler specific - optimisations. Note I am unsure of Microsoft version numbers. So I - suspect are Microsoft. - - Note: It seems to be impossible to get the 16-bit Microsoft compiler - to allow inline 32-bit op-codes. So I suspect that INLINE_ASM == 2 will - never work with it. Pity. - -#define INLINE_ASM 1 -> generates 8086 inline assembly -#define INLINE_ASM 2 -> generates mixed 8086 & 80386 inline assembly, - so you can get some benefit while running in a - 16-bit environment on 32-bit hardware (DOS, Windows - 3.1...) -#define INLINE_ASM 3 -> generate true 80386 inline assembly - (Using DOS - extender, Windows '95/Windows NT) - Actually optimised for Pentium - -#define INLINE_ASM 4 -> 80386 code in the GNU style (for (DJGPP) - -Small, medium, compact and large memory models are supported for the -first two of the above. - -*/ - -/* To allow for inline assembly */ - -#ifdef __GNUC__ - #define ASM __asm__ __volatile__ -#endif - -#ifdef __TURBOC__ - #define ASM asm -#endif - -#ifdef _MSC_VER - #define ASM _asm -#endif - -#ifndef MR_NOASM - -/* Win64 - inline the time critical function */ -#ifndef MR_NO_INTRINSICS - #ifdef MR_WIN64 - #define muldvd(a,b,c,rp) (*(rp)=_umul128((a),(b),&(tm)),*(rp)+=(c),tm+=(*(rp)<(c)),tm) - #define muldvd2(a,b,c,rp) (tr=_umul128((a),(b),&(tm)),tr+=(*(c)),tm+=(tr<(*(c))),tr+=(*(rp)),tm+=(tr<(*(rp))),*(rp)=tr,*(c)=tm) - #endif - -/* Itanium - inline the time-critical functions */ - - #ifdef MR_ITANIUM - #define muldvd(a,b,c,rp) (tm=_m64_xmahu((a),(b),(c)),*(rp)=_m64_xmalu((a),(b),(c)),tm) - #define muldvd2(a,b,c,rp) (tm=_m64_xmalu((a),(b),(*(c))),*(c)=_m64_xmahu((a),(b),(*(c))),tm+=*(rp),*(c)+=(tm<*(rp)),*(rp)=tm) - #endif -#endif -/* - -SSE2 code. Works as for itanium - but in fact it is slower than the regular code so not recommended -Would require a call to emmintrin.h or xmmintrin.h, and an __m128i variable tm to be declared in effected -functions. But it works! - - #define muldvd(a,b,c,rp) (tm=_mm_add_epi64(_mm_mul_epu32(_mm_cvtsi32_si128((a)),_mm_cvtsi32_si128((b))),_mm_cvtsi32_si128((c))),*(rp)=_mm_cvtsi128_si32(tm),_mm_cvtsi128_si32(_mm_shuffle_epi32(tm,_MM_SHUFFLE(3,2,0,1))) ) - #define muldvd2(a,b,c,rp) (tm=_mm_add_epi64(_mm_add_epi64(_mm_mul_epu32(_mm_cvtsi32_si128((a)),_mm_cvtsi32_si128((b))),_mm_cvtsi32_si128(*(c))),_mm_cvtsi32_si128(*(rp))),*(rp)=_mm_cvtsi128_si32(tm),*(c)=_mm_cvtsi128_si32( _mm_shuffle_epi32(tm,_MM_SHUFFLE(3,2,0,1)) ) -*/ - -/* Borland C/Turbo C */ - - #ifdef __TURBOC__ - #ifndef __HUGE__ - #if defined(__COMPACT__) || defined(__LARGE__) - #define MR_LMM - #endif - - #if MIRACL==16 - #define INLINE_ASM 1 - #endif - - #if __TURBOC__>=0x410 - #if MIRACL==32 -#if defined(__SMALL__) || defined(__MEDIUM__) || defined(__LARGE__) || defined(__COMPACT__) - #define INLINE_ASM 2 - #else - #define INLINE_ASM 3 - #endif - #endif - #endif - #endif - #endif - -/* Microsoft C */ - - #ifdef _MSC_VER - #ifndef M_I86HM - #if defined(M_I86CM) || defined(M_I86LM) - #define MR_LMM - #endif - #if _MSC_VER>=600 - #if _MSC_VER<1200 - #if MIRACL==16 - #define INLINE_ASM 1 - #endif - #endif - #endif - #if _MSC_VER>=1000 - #if _MSC_VER<1500 - #if MIRACL==32 - #define INLINE_ASM 3 - #endif - #endif - #endif - #endif - #endif - -/* DJGPP GNU C */ - - #ifdef __GNUC__ - #ifdef i386 - #if MIRACL==32 - #define INLINE_ASM 4 - #endif - #endif - #endif - -#endif - - - -/* - The following contribution is from Tielo Jongmans, Netherlands - These inline assembler routines are suitable for Watcom 10.0 and up - - Added into miracl.h. Notice the override of the original declarations - of these routines, which should be removed. - - The following pragma is optional, it is dangerous, but it saves a - calling sequence -*/ - -/* - -#pragma off (check_stack); - -extern unsigned int muldiv(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int *); -#pragma aux muldiv= \ - "mul edx" \ - "add eax,ebx" \ - "adc edx,0" \ - "div ecx" \ - "mov [esi],edx" \ - parm [eax] [edx] [ebx] [ecx] [esi] \ - value [eax] \ - modify [eax edx]; - -extern unsigned int muldvm(unsigned int, unsigned int, unsigned int, unsigned int *); -#pragma aux muldvm= \ - "div ebx" \ - "mov [ecx],edx" \ - parm [edx] [eax] [ebx] [ecx] \ - value [eax] \ - modify [eax edx]; - -extern unsigned int muldvd(unsigned int, unsigned int, unsigned int, unsigned int *); -#pragma aux muldvd= \ - "mul edx" \ - "add eax,ebx" \ - "adc edx,0" \ - "mov [ecx],eax" \ - "mov eax,edx" \ - parm [eax] [edx] [ebx] [ecx] \ - value [eax] \ - modify [eax edx]; - -*/ - - -#endif - - diff --git a/generator_cgo/include/mirdef.h b/generator_cgo/include/mirdef.h deleted file mode 100644 index 54fa13a..0000000 --- a/generator_cgo/include/mirdef.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * MIRACL compiler/hardware definitions - mirdef.h - */ - -#define MR_LITTLE_ENDIAN -#define MIRACL 64 -#define mr_utype long long -#define mr_unsign64 unsigned long long -#define MR_IBITS 32 -#define MR_LBITS 64 -#define mr_unsign32 unsigned int -#define MR_FLASH 52 -#define MAXBASE ((mr_small)1<<(MIRACL-1)) -#define MR_BITSINCHAR 8 - diff --git a/generator_cgo/include/sign.h b/generator_cgo/include/sign.h deleted file mode 100644 index 20ca11f..0000000 --- a/generator_cgo/include/sign.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __SIGN_H__ -#define __SIGN_H__ - -#include "ecurve.h" -#include "miracl.h" -#include "mirdef.h" -#include - -void getFullkey( - ECC_PARAMS *params, - char *ID, // 用户ID - big d, // 用户部分私钥 - big x, // 用户秘密值 - epoint *X, // 用户公钥 - big sa // 用户完整私钥 -); - -void sign_Thumbur( - ECC_PARAMS *params, - char *ID, // 用户ID - char *msg, // 签名消息 - big sa, // 用户完整私钥 - epoint *Q, // 用户完整公钥 - epoint *U, // 输出签名的随机数变换 - epoint *PK_pub, //kgc公钥 - big v // 输出签名的计算值 -); - -bool verify_Thumbur( - ECC_PARAMS *params, - char *ID, - char *msg, - epoint *Q, - epoint *PK_pub, - epoint *U, - big v -); - -#endif \ No newline at end of file diff --git a/generator_cgo/include/utils.h b/generator_cgo/include/utils.h deleted file mode 100644 index 90ad46f..0000000 --- a/generator_cgo/include/utils.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __UNTILS_H__ -#define __UNTILS_H__ - - -#include "miracl.h" -#include "mirdef.h" -#include "ecurve.h" - -void outbig(big num, char *val_name); - -void outpoint(epoint *PO, char *val_name); - -void setRandSeed(); - -void sha256_update_string(sha256 sh, const char *data, long data_len); - -void sha256_update_point(sha256 sh, epoint *point); - -void genSecret(ECC_PARAMS *params, big x, epoint *X); - -bool Setup(); - - -#endif \ No newline at end of file diff --git a/generator_cgo/include/zzn.h b/generator_cgo/include/zzn.h deleted file mode 100644 index 850df10..0000000 --- a/generator_cgo/include/zzn.h +++ /dev/null @@ -1,219 +0,0 @@ - -/*************************************************************************** - * -Copyright 2013 CertiVox UK Ltd. * - * -This file is part of CertiVox MIRACL Crypto SDK. * - * -The CertiVox MIRACL Crypto SDK provides developers with an * -extensive and efficient set of cryptographic functions. * -For further information about its features and functionalities please * -refer to http://www.certivox.com * - * -* The CertiVox MIRACL Crypto SDK is free software: you can * - redistribute it and/or modify it under the terms of the * - GNU Affero General Public License as published by the * - Free Software Foundation, either version 3 of the License, * - or (at your option) any later version. * - * -* The CertiVox MIRACL Crypto SDK is distributed in the hope * - that it will be useful, but WITHOUT ANY WARRANTY; without even the * - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * - See the GNU Affero General Public License for more details. * - * -* You should have received a copy of the GNU Affero General Public * - License along with CertiVox MIRACL Crypto SDK. * - If not, see . * - * -You can be released from the requirements of the license by purchasing * -a commercial license. Buying such a license is mandatory as soon as you * -develop commercial activities involving the CertiVox MIRACL Crypto SDK * -without disclosing the source code of your own applications, or shipping * -the CertiVox MIRACL Crypto SDK with a closed source product. * - * -***************************************************************************/ -/* - * - * MIRACL C++ Header file zzn.h - * - * AUTHOR : M. Scott - * - * PURPOSE : Definition of class ZZn (Arithmetic mod n), using - * Montgomery's Method for modular multiplication - * NOTE : Must be used in conjunction with zzn.cpp - * The modulus n is always set dynamically (via the modulo() - * routine) - so beware the pitfalls implicit in declaring - * static or global ZZn's (which are initialised before n is - * set!). Uninitialised data is OK - */ - -#ifndef ZZN_H -#define ZZN_H - -#include "big.h" - -/* - -#ifdef ZZNS -#define MR_INIT_ZZN memset(mem,0,mr_big_reserve(1,ZZNS)); fn=(big)mirvar_mem_variable(mem,0,ZZNS); -#define MR_CLONE_ZZN(x) fn->len=x->len; for (int i=0;iw[i]=x->w[i]; -#define MR_ZERO_ZZN {fn->len=0; for (int i=0;iw[i]=0;} -#else -#define MR_INIT_ZZN mem=(char *)memalloc(1); fn=(big)mirvar_mem(mem,0); -#define MR_CLONE_ZZN(x) copy(x,fn); -#define MR_ZERO_ZZN zero(fn); -#endif - -*/ - -#ifdef ZZNS -#ifdef MR_COMBA -#define UZZNS ZZNS -#else -#define UZZNS ZZNS+1 // one extra required in case of carry overflow in addition -#endif -#endif - -#ifdef ZZNS -#define MR_INIT_ZZN fn=&b; b.w=a; b.len=UZZNS; -#define MR_CLONE_ZZN(x) b.len=x->len; for (int i=0;iw[i]; -#define MR_ZERO_ZZN {b.len=0; for (int i=0;i ZZn */ - ZZn(big& c) {MR_INIT_ZZN MR_CLONE_ZZN(c);} - ZZn(const ZZn& c) {MR_INIT_ZZN MR_CLONE_ZZN(c.fn);} - ZZn(char* s) {MR_INIT_ZZN cinstr(fn,s); nres(fn,fn);} - - ZZn& operator=(const ZZn& c) {MR_CLONE_ZZN(c.fn) return *this;} - ZZn& operator=(big c) {MR_CLONE_ZZN(c) return *this; } - - ZZn& operator=(int i) {if (i==0) MR_ZERO_ZZN else {convert(i,fn); nres(fn,fn);} return *this;} - ZZn& operator=(char* s){cinstr(fn,s); nres(fn,fn); return *this;} - - -/* Use fast in-line code */ - - ZZn& operator++() - {nres_modadd(fn,get_mip()->one,fn);return *this;} - ZZn& operator--() - {nres_modsub(fn,get_mip()->one,fn);return *this;} - ZZn& operator+=(int i) - {ZZn inc=i; nres_modadd(fn,inc.fn,fn);return *this;} - ZZn& operator-=(int i) - {ZZn dec=i; nres_modsub(fn,dec.fn,fn); return *this;} - ZZn& operator+=(const ZZn& b) - {nres_modadd(fn,b.fn,fn); return *this;} - ZZn& operator-=(const ZZn& b) - {nres_modsub(fn,b.fn,fn); return *this;} - ZZn& operator*=(const ZZn& b) - {nres_modmult(fn,b.fn,fn); return *this;} - ZZn& operator*=(int i) - {nres_premult(fn,i,fn); return *this;} - - ZZn& negate() - {nres_negate(fn,fn); return *this;} - - BOOL iszero() const; - - operator Big() {Big c; redc(fn,c.getbig()); return c;} /* ZZn -> Big */ - friend big getbig(ZZn& z) {return z.fn;} - - ZZn& operator/=(const ZZn& b) {nres_moddiv(fn,b.fn,fn); return *this;} - ZZn& operator/=(int); - - friend ZZn operator-(const ZZn&); - friend ZZn operator+(const ZZn&,int); - friend ZZn operator+(int, const ZZn&); - friend ZZn operator+(const ZZn&, const ZZn&); - - friend ZZn operator-(const ZZn&, int); - friend ZZn operator-(int, const ZZn&); - friend ZZn operator-(const ZZn&, const ZZn&); - - friend ZZn operator*(const ZZn&,int); - friend ZZn operator*(int, const ZZn&); - friend ZZn operator*(const ZZn&, const ZZn&); - - friend ZZn operator/(const ZZn&, int); - friend ZZn operator/(int, const ZZn&); - friend ZZn operator/(const ZZn&, const ZZn&); - - friend BOOL operator==(const ZZn& b1,const ZZn& b2) - { if (mr_compare(b1.fn,b2.fn)==0) return TRUE; else return FALSE;} - friend BOOL operator!=(const ZZn& b1,const ZZn& b2) - { if (mr_compare(b1.fn,b2.fn)!=0) return TRUE; else return FALSE;} - - friend ZZn one(void); - friend ZZn pow( const ZZn&, const Big&); - friend ZZn pow( const ZZn&,int); - friend ZZn powl(const ZZn&, const Big&); - friend ZZn pow( const ZZn&, const Big&, const ZZn&, const Big&); - friend ZZn pow( int,ZZn *,Big *); - friend int jacobi(const ZZn&); -#ifndef MR_NO_RAND - friend ZZn randn(void); // random number < modulus -#endif - friend BOOL qr(const ZZn&); // test for quadratic residue - friend BOOL qnr(const ZZn&); // test for quadratic non-residue - friend ZZn getA(void); // get A parameter of elliptic curve - friend ZZn getB(void); // get B parameter of elliptic curve - - friend ZZn sqrt(const ZZn&); // only works if modulus is prime - - friend ZZn luc( const ZZn& b1, const Big& b2, ZZn* b3=NULL) - { - ZZn z; if (b3!=NULL) nres_lucas(b1.fn,b2.getbig(),b3->fn,z.fn); - else nres_lucas(b1.fn,b2.getbig(),z.fn,z.fn); - return z; - } - - //friend ZZn luc( const ZZn&, const Big&, ZZn* b3=NULL); - - big getzzn(void) const; - -#ifndef MR_NO_STANDARD_IO - friend ostream& operator<<(ostream&,const ZZn&); -#endif - - - ~ZZn() - { - // MR_ZERO_ZZN // slower but safer -#ifndef ZZNS - mr_free(fn); -#endif - } -}; -#ifndef MR_NO_RAND -extern ZZn randn(void); -#endif -extern ZZn getA(void); -extern ZZn getB(void); -extern ZZn one(void); - -#endif - diff --git a/generator_cgo/lib/libKGC.a b/generator_cgo/lib/libKGC.a deleted file mode 100644 index ca2796ea8437683cd6537b970bf6b5042129d8a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14968 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 diff --git a/generator_cgo/lib/libMiracl.a b/generator_cgo/lib/libMiracl.a deleted file mode 100644 index 34cf199d70897ba9398b99e8388df7e8570bb732..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 418988 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%0D?Ex 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

jAIE#YlIQcj-$x{~=FRDWrGjSe~kiT+Lp z65U@0BvKVAngJwQD^*$rkZ3Kcw1&esBoHl_mQafpbb zDn$<|TCM1LMXxLROwnOQT?QJ?=PMebs7TQ?MRzE=PthtxPb+#&(MO6t2a-Ix>r#_S zThZe{*K;bL1RBfe>_NugMT$lOiN8@m;%_0)4IJWLpb3nA0VMhR0g&WElcIAjv#cB0 z-$q5-6@9MgsG+^YcJbBHmMU2Q&SqNXpAdAn|vt zy56X0q589dq~!cYU7uI2Yb+HH!WipY|IxV{J^{N7RIMRO#z zq9;%ubMCKbf}&d#-KA)$qTd0DeBS|$V=kv4GX$LlBq_Q;Q5Z<{ay^jfWvNdjGEIMMe2=l9XQyBq^V&Xn~>{MNcW(r05+* zpDFT$jW#9%i4Ja8^q``@D0&u1WZtCcQy|gMAt2GviG_yN6G&(mD=klHvz4|`Y3E|P zBK2(^kZ5hAqO-3xv;~T;9b=>#g{UON?-U(VG!9NqE}+^$4Je(}itbYsz24|0;|5bE zPf=8$=qEtJ9FQ05Q)TC(06hn(Ddal@{{KTmy-gAIN(*8iA zms~}|6wOrhK9HpH#%X4Sc?l52LC*YK(P~9?K*$`p?of0U|R%_c-d(Ort}QS^wS7l2T0puZ8bjih4~H2_JzeWA3jbBw<}Koa&Upb^YvyrOA} zN)`PKNF;p~2n7o9zOCp3MQ6@6<+Qh=i-DwU+yNxbea`q)(k^%E1{x zKjwJ*0p&3orsz6FvlT5>^czL%6uqoym!fYJtuL`GR1u_d7Z9ol(07Wu-D+t473~9( zI&(s)LEV7zIcyD(q-YzEq+>gf=p}c)Nzq6};}lI(bep1k6b+4-uvaU35@;C5`^yDp z&8QKmh-n`H4PmqwXegua6`g#Wq4|L%kH!N@i!@8o4j?o;(94{1limtNPbk_6bS?X9 z0upVUce~L>4v=tuOlc3_X*Bd3pj;077Lb&`PZeb>G$}t*QGZ20R#c>DvZCFJ_9;51 z=%l+0=PX6pijFBdd6Drq0Z4Q;A4pQPP*I1wjjnzJB-;2BkZ9v?KvDov^c&R-y=%%yBJO8j6skwF-5uQd*6orRrL%v^(m#TSM;2^)+ue1qOI!siqaYty{WF-mG-WpUF!O=(wY?QQP+J+`&v

; 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 -#include -#include -char* IDA = "1234567890111213141516171819202122232425"; // 发送者ID -char* IDB = "1448579437597582757693565726417498574267"; // 接受者ID -char* M = "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"; -char* msk = "msk"; -char* PKP = "PK_pub"; -char* Public = "P_P"; -char* QA = "Q_A"; -char* dA = "d_A"; -char* xA = "x_A"; -char* XA = "X_A"; -char* saA = "sa_A"; -*/ -import "C" -import "fmt" - -func main() { - - mip := C.mirsys(512, 16) // 初始化MIRACL系统,512位,16进制数 - mip.IOBASE = 16 // 设置大整数为16进制 - a := C.mirvar(0) - C.mirkill(a) - C.setRandSeed() - - // 建立椭圆曲线 - var params C.ECC_PARAMS - if !C.setupEcurve(¶ms) { - fmt.Println("ecurve setup failed") - C.mirexit() - panic("椭圆曲线建立失败!") - } - - C.setRandSeed() // 随机数种子 - //初始化参数 - msk := C.mirvar(0) //私钥 - PK_pub := C.epoint_init() //公钥 - d_A := C.mirvar(0) //用户A产生的部分私钥 - x_A := C.mirvar(0) //用户产生的秘密值 - X_A := C.epoint_init() - sa_A := C.mirvar(0) //用户完整私钥 - Q_A := C.epoint_init() //用户完整公钥 - val := C.mirvar(0) //用户返回的签名值 - U := C.epoint_init() //随机点值 - - // 产生KGC密钥对: msk, PK_pub - C.genKGCkey(¶ms, msk, PK_pub) - C.outbig(msk, C.msk) - - C.outpoint((¶ms).P, C.Public) - C.outpoint(PK_pub, C.PKP) - - // 产生用户A的秘密值 - C.genSecret(¶ms, x_A, X_A) - C.outbig(x_A, C.xA) - C.outpoint(X_A, C.XA) - - // 产生用户A的部分私钥和用户的完整公钥 - if !C.genPPK_std(¶ms, msk, PK_pub, C.IDA, d_A, Q_A, X_A) { - fmt.Println("Generate PPK for IDA failed.") - goto error - } - C.outbig(d_A, C.dA) - C.outpoint(Q_A, C.QA) - - // 输出完整的用户私钥 - C.getFullkey(¶ms, C.IDA, d_A, x_A, X_A, sa_A) - C.outbig(sa_A, C.saA) - - // 签名,Gowri Thumbur方案 - C.sign_Thumbur(¶ms, C.IDA, C.M, sa_A, Q_A, U, PK_pub, val) - - // 验签 - if C.verify_Thumbur(¶ms, C.IDA, C.M, Q_A, PK_pub, U, val) { - fmt.Println("\nsignature valid.") - } else { - fmt.Println("\nverify failed.") - } - -error: - C.mirkill(msk) - C.mirkill(d_A) - C.mirkill(x_A) - C.mirkill(sa_A) - C.epoint_free(PK_pub) - C.epoint_free(X_A) - C.epoint_free(Q_A) - C.epoint_free(U) - - C.freeEcurve(¶ms) - C.mirexit() // 退出MIRACL系统 - -} diff --git a/generator_cgo/params.txt b/generator_cgo/params.txt deleted file mode 100644 index 84ed46b..0000000 --- a/generator_cgo/params.txt +++ /dev/null @@ -1,19 +0,0 @@ -char str_msk[] = "6D5DB11261A93275CD69A813F6CA4FE84A5613B346D27AFEFAF3D63D0DF307A7"; -char str_P_P_x[]= "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"; -char str_P_P_y[]= "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8"; -char str_PK_pub_x[]= "6C723EBEDA3B3FF230BEFEB870DBCF38271F609A09E949FA06E512C74FEB4E76"; -char str_PK_pub_y[]= "5FAE4EB8F8B38B401C231D4EB682E53977A62663169B1B1908F4906E4758DD7C"; -char str_x_A[] = "80A80E35FB678995DE03E0DE6DCA75651D48D57C82923C4F8097A7CF80FFDC0F"; -char str_X_A_x[]= "3E9FD587517E568102447F7BFDA9955EAFF9F8984DE497813269546ADAB30D8A"; -char str_X_A_y[]= "3AC044504324E5FD14D16FC396133EE7FD4B4743E0F4F3245BF69F3634CD74F4"; -char str_d_A[] = "37F0619702B66C78D898A2135FAF59AFF5439BBA388FB114CEDA6180FF8E395C"; -char str_sa_A[] = "6A7C930DDCFE3B505D5AD7824B63ABA9110883D261CE67C04AF01E395E248766"; -char str_Q_A_x[]= "6E87706053DD52225354602E031A1D025115B54B8C600D3C47AB66749D0852DC"; -char str_Q_A_y[]= "71C165DCBF5E07903517A5AAB4919104229A1E65D6D57C23B95147ED79BA23E4"; -char str_v[] = "33979BEB2B89412DEA04EC7DD07FF8F98792F490A6A519AE64766BAE30B7874A"; -signature valid. - -用户ID:char* IDA = "1234567890111213141516171819202122232425"; -用户私钥:char str_sa_A[] = "6A7C930DDCFE3B505D5AD7824B63ABA9110883D261CE67C04AF01E395E248766"; -用户公钥:char str_Q_A_x[]= "6E87706053DD52225354602E031A1D025115B54B8C600D3C47AB66749D0852DC"; - char str_Q_A_y[]= "71C165DCBF5E07903517A5AAB4919104229A1E65D6D57C23B95147ED79BA23E4"; diff --git a/generator_cgo/include/hash.cpp b/hash.c similarity index 100% rename from generator_cgo/include/hash.cpp rename to hash.c diff --git a/hash.cpp b/hash.cpp deleted file mode 100644 index 82e9d5b..0000000 --- a/hash.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include "hash.h" -#include "ecurve.h" -#include "utils.h" - -void hash1(char *ID, epoint *Q, epoint *PK_pub, big p, big h_1_big) -{ - // 计算hash值H_1(ID, R, PK_pub) - //hash1(ID, Q, PK_pub) - sha256 sh; - char h_1[33] = {0}; - - shs256_init(&sh); - sha256_update_string(sh, ID, strlen(ID)); - sha256_update_point(sh, Q); - sha256_update_point(sh, PK_pub); - shs256_hash(&sh, h_1); - - bytes_to_big(32, h_1, h_1_big); - power(h_1_big, 1, p, h_1_big); // mod p -} - -void hash2(char *ID, epoint *X, big p, big h_2_big) -{ - // 计算hash值H_2(ID, X) - sha256 sh; - char h_2[33] = {0}; - - shs256_init(&sh); - sha256_update_string(sh, ID, strlen(ID)); - sha256_update_point(sh, X); - shs256_hash(&sh, h_2); - - bytes_to_big(32, h_2, h_2_big); - power(h_2_big, 1, p, h_2_big); // mod p -} - -void hash3( - char *ID, - char *msg, - epoint *Q, - epoint *U, - epoint *PK_pub, - big p, - big h_3_big -) -{ - sha256 sh; - char h_3[33] = {0}; - - shs256_init(&sh); - sha256_update_string(sh, ID, strlen(ID)); - sha256_update_string(sh, msg, strlen(msg)); - sha256_update_point(sh, Q); - sha256_update_point(sh, U); - sha256_update_point(sh, PK_pub); - shs256_hash(&sh, h_3); - - bytes_to_big(32, h_3, h_3_big); - power(h_3_big, 1, p, h_3_big); // mod p -} diff --git a/hash.h b/hash.h index aab82a8..5e3a0e8 100644 --- a/hash.h +++ b/hash.h @@ -1,11 +1,9 @@ #ifndef __HASH_H__ #define __HASH_H__ -extern "C" -{ +#include #include "miracl.h" #include "mirdef.h" -} //hash1(ID, Q, PK_pub, h_1_big) void hash1(char *ID, epoint *Q, epoint *PK_pub, big p, big h_1_big); diff --git a/generator_cgo/include/kgc.cpp b/kgc.c similarity index 100% rename from generator_cgo/include/kgc.cpp rename to kgc.c diff --git a/kgc.cpp b/kgc.cpp deleted file mode 100644 index 4d9e0aa..0000000 --- a/kgc.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include "kgc.h" -#include "hash.h" - -void genKGCkey(ECC_PARAMS *params, big msk, epoint *PK_pub) -{ - bigrand((*params).p, msk); // 产生小于p的随机数 - ecurve_mult(msk, (*params).P, PK_pub); -} - -bool genPPK_std( - ECC_PARAMS *params, - big msk, // KGC私钥 - epoint *PK_pub, // KGC公钥 - char ID[], // 输入用户ID - big d, // 输出部分私钥 - epoint *Q, // 产生的用户公钥 - epoint *X) // 输入用户秘密值 -{ - // 产生随机数r,计算R=rP - epoint *R_A = epoint_init(); - big r = mirvar(0); - bigrand((*params).p, r); - ecurve_mult(r, (*params).P, R_A); - - //计算h_2 = H_2(ID,X) - big h_2_big = mirvar(0); - hash2(ID, X, (*params).p, h_2_big); - - //计算h_2 * X - epoint *h2X = epoint_init(); - ecurve_mult(h_2_big, X, h2X); - - //计算Q = R + h_2 * X - ecurve_add(R_A, Q); - ecurve_add(h2X, Q); - - //计算h_1 = H_1(ID,Q,PK_pub) - big h_1_big = mirvar(0); - hash1(ID, Q, PK_pub, (*params).p, h_1_big); - - // 计算d = r + msk * h_1 mod p - big tmp = mirvar(0); - multiply(msk, h_1_big, tmp); - add(r, tmp, d); - power(d, 1, (*params).p, d); // mod p - - //计算h_1 * PK_pub - epoint *h1PK = epoint_init(); - ecurve_mult(h_1_big, PK_pub, h1PK); - - // 用d * P = Q - h2 * X + h1 * PK_pub验证一下(d,Q)是否正确 - // 点的减法 pa = pa - a Function: void ecurve_sub(p,pa) - epoint *left = epoint_init(); - ecurve_mult(d, (*params).P, left); - epoint *right = epoint_init(); - ecurve_add(Q, right); - ecurve_sub(h2X, right); - ecurve_add(h1PK, right); - - bool bRv = false; - if (epoint_comp(left, right)) - { - bRv = true; - - } - else - { - bRv = false; - } - - mirkill(r); - mirkill(h_1_big); - mirkill(h_2_big); - mirkill(tmp); - - epoint_free(R_A); - epoint_free(left); - epoint_free(right); - epoint_free(h1PK); - epoint_free(h2X); - - return bRv; -} \ No newline at end of file diff --git a/miracl/CMakeLists.txt b/miracl/CMakeLists.txt index f985024..60be99f 100644 --- a/miracl/CMakeLists.txt +++ b/miracl/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.21) -project(Miracl) +project(Miracl LANGUAGES C) include(GNUInstallDirs) diff --git a/generator_cgo/include/sign.cpp b/sign.c similarity index 100% rename from generator_cgo/include/sign.cpp rename to sign.c diff --git a/sign.cpp b/sign.cpp deleted file mode 100644 index 852ee76..0000000 --- a/sign.cpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include -#include "sign.h" -#include "hash.h" -#include "utils.h" - -void getFullkey( - ECC_PARAMS *params, - char *ID, // 用户ID - big d, // 用户部分私钥 - big x, // 用户秘密值 - epoint *X, // 用户公钥 - big sa // 用户完整私钥 -) -{ - // 计算hash值H_2(ID, X) - big h_2_big = mirvar(0); - hash2(ID, X, (*params).p, h_2_big); - - // 计算sa = d + h_2*x mod p - big tmp = mirvar(0); - multiply(x, h_2_big, tmp); - add(d, tmp, sa); - power(sa, 1, (*params).p, sa); // mod p - - mirkill(h_2_big); - mirkill(tmp); -} - -void sign_Thumbur( - ECC_PARAMS *params, - char *ID, // 用户ID - char *msg, // 签名消息 - big sa, // 输入用户完整私钥 - epoint *Q, // 输入用户完整公钥 - epoint *U, // 输出签名的随机数变换 - epoint *PK_pub, //输入KGC的公钥 - big v // 输出签名的计算值 -) -{ - // 产生随机数u,计算U=uP - big u = mirvar(0); - bigrand((*params).p, u); - ecurve_mult(u, (*params).P, U); - - // 计算hash值H_3(ID, msg, Q, U, PK_pub) - big h_3_big = mirvar(0); - hash3(ID, msg, Q, U, PK_pub, (*params).p, h_3_big); - - // 计算签名值 v = u + h_3*sa - big tmp = mirvar(0); - multiply(sa, h_3_big, tmp); - add(u, tmp, v); - power(v, 1, (*params).p, v); // mod p - outbig(v, "v"); - - mirkill(u); - mirkill(h_3_big); - mirkill(tmp); -} - -bool verify_Thumbur( - ECC_PARAMS *params, - char *ID, - char *msg, - epoint *Q, - epoint *PK_pub, - epoint *U, - big v -) -{ - // 计算hash值H_1(ID, Q, PK_pub) - big h_1_big = mirvar(0); - hash1(ID, Q, PK_pub, (*params).p, h_1_big); - - // 计算hash值H_3(ID, msg, Q, U, PK_pub) - big h_3_big = mirvar(0); - hash3(ID, msg, Q, U, PK_pub, (*params).p, h_3_big); - - // 验签等式 v*P = U + h_3(Q + h_1*P_pub) - // 等式左边: - epoint *left = epoint_init(); - ecurve_mult(v, (*params).P, left); - - // 等式右边: - epoint *tmp_p = epoint_init(); - ecurve_mult(h_1_big, PK_pub, tmp_p); - ecurve_add(Q, tmp_p); - ecurve_mult(h_3_big, tmp_p, tmp_p); - ecurve_add(U, tmp_p); - - bool bRv = false; - if (epoint_comp(left, tmp_p)) - { - bRv = true; - } - else - { - bRv = false; - } - - mirkill(h_1_big); - mirkill(h_3_big); - epoint_free(left); - epoint_free(tmp_p); - return bRv; -} \ No newline at end of file diff --git a/generator_cgo/include/utils.cpp b/utils.c similarity index 100% rename from generator_cgo/include/utils.cpp rename to utils.c diff --git a/utils.cpp b/utils.cpp deleted file mode 100644 index 394c78c..0000000 --- a/utils.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include "utils.h" -#include "ecurve.h" -#include "kgc.h" - -//将big大数类型转为char*类型 -void outbig(big num, char *val_name) -{ - char out_str[257] = {0}; - cotstr(num, out_str); - printf("\nchar str_%s[] = \"%s\";", val_name, out_str); -} - -//将big大数类型转为char*类型 -void outpoint(epoint *PO, char *val_name) -{ - char out_str[257] = {0}; - big PO_x = mirvar(0); - big PO_y = mirvar(0); - epoint_get(PO, PO_x, PO_y); - cotstr(PO_x, out_str); - printf("\nchar str_%s_x[]= \"%s\";", val_name, out_str); - cotstr(PO_y, out_str); - printf("\nchar str_%s_y[]= \"%s\";", val_name, out_str); -} - -// 设置随机数种子 -void setRandSeed() -{ - time_t seed; - time(&seed); // 用系统时间做种子 - irand((long)seed); - return; -} - -// -void sha256_update_string(sha256 sh, const char *data, long data_len) -{ - for (long i = 0; i < data_len; i++) - { - shs256_process(&sh, data[i]); - } -} - -void sha256_update_point(sha256 sh, epoint *point) -{ - big point_x = mirvar(0); - big point_y = mirvar(0); - char point_x_string[256] = {0}; - char point_y_string[256] = {0}; - epoint_get(point, point_x, point_y); - cotstr(point_x, point_x_string); - cotstr(point_y, point_y_string); - - for (unsigned int i = 0; i < strlen(point_x_string); i++) - { - shs256_process(&sh, point_x_string[i]); - } - - for (unsigned int i = 0; i < strlen(point_y_string); i++) - { - shs256_process(&sh, point_y_string[i]); - } - - mirkill(point_x); - mirkill(point_y); -} - -//用户产生秘密值x,以及与基点点乘后的X -void genSecret(ECC_PARAMS *params, big x, epoint *X) -{ - bigrand((*params).p, x); //产生小于阶p的big值 - ecurve_mult(x, (*params).P, X); -} diff --git a/utils.h b/utils.h index 10e70d6..9ad9669 100644 --- a/utils.h +++ b/utils.h @@ -1,11 +1,8 @@ #ifndef __UNTILS_H__ #define __UNTILS_H__ -extern "C" -{ #include "miracl.h" #include "mirdef.h" -} #include "ecurve.h" void outbig(big num, char *val_name);