├── .github
├── images
│ ├── Dockerfile.build
│ └── context.build
│ │ └── .gitkeep
└── workflows
│ └── build.yml
├── .gitignore
├── .gitmodules
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── CMakeLists.txt
├── COPYING
├── Makefile
├── README.md
├── build
├── fq.asm
├── fq.cpp
├── fq.hpp
├── fq_element.hpp
├── fq_generic.cpp
├── fq_raw_arm64.s
├── fq_raw_generic.cpp
├── fr.asm
├── fr.cpp
├── fr.hpp
├── fr_element.hpp
├── fr_generic.cpp
├── fr_raw_arm64.s
└── fr_raw_generic.cpp
├── build_gmp.sh
├── cmake
└── platform.cmake
├── package-lock.json
├── package.json
├── service
├── README.md
└── rapidsnark.service
├── src
├── CMakeLists.txt
├── binfile_utils.cpp
├── binfile_utils.hpp
├── fileloader.cpp
├── fileloader.hpp
├── fullprover.cpp
├── fullprover.hpp
├── groth16.cpp
├── groth16.hpp
├── logger.cpp
├── logger.hpp
├── logging.hpp
├── main_proofserver.cpp
├── main_prover.cpp
├── main_verifier.cpp
├── prover.cpp
├── prover.h
├── proverapi.cpp
├── proverapi.hpp
├── random_generator.hpp
├── test_prover.cpp
├── test_public_size.c
├── verifier.cpp
├── verifier.h
├── wtns_utils.cpp
├── wtns_utils.hpp
├── zkey_utils.cpp
└── zkey_utils.hpp
├── tasksfile.js
├── testdata
├── circuit_final.zkey
├── verification_key.json
└── witness.wtns
└── tools
└── request.js
/.github/images/Dockerfile.build:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | RUN apt-get -y update && \
4 | apt-get -y install build-essential cmake m4 nasm curl
5 |
--------------------------------------------------------------------------------
/.github/images/context.build/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iden3/rapidsnark/998383787ee86bcb6bfb8741e9a638d203c08eae/.github/images/context.build/.gitkeep
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | # build/
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 |
63 | tmp
64 |
65 | .DS_Store
66 |
67 | # Workspace files are user-specific
68 | *.sublime-workspace
69 | CMakeLists.txt.user
70 |
71 | depends/gmp*
72 |
73 | build_*
74 | package*
75 |
76 | build/fq_asm.o
77 | build/fr_asm.o
78 |
79 | .idea/
80 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "depends/pistache"]
2 | path = depends/pistache
3 | url = https://github.com/pistacheio/pistache
4 | [submodule "depends/json"]
5 | path = depends/json
6 | url = https://github.com/nlohmann/json.git
7 | [submodule "depends/ffiasm"]
8 | path = depends/ffiasm
9 | url = https://github.com/iden3/ffiasm
10 | branch = master
11 | [submodule "depends/circom_runtime"]
12 | path = depends/circom_runtime
13 | url = https://github.com/iden3/circom_runtime.git
14 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "proofServer",
9 | "type": "cppdbg",
10 | "request": "launch",
11 | "program": "${workspaceFolder}/build/proverServer",
12 | "args": ["/home/jordi/circuits/tools/rollup-376-32-256-64/circuit-376-32-256-64.dat", "/home/jordi/circuits/tools/rollup-376-32-256-64/circuit-376-32-256-64_0001.zkey" ],
13 | "stopAtEntry": false,
14 | "cwd": "${workspaceFolder}/build",
15 | "environment": [],
16 | "externalConsole": false,
17 | "MIMode": "gdb",
18 | "setupCommands": [
19 | {
20 | "description": "Enable pretty-printing for gdb",
21 | "text": "-enable-pretty-printing",
22 | "ignoreFailures": true
23 | }
24 | ]
25 | }
26 | ]
27 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "array": "cpp",
4 | "atomic": "cpp",
5 | "bit": "cpp",
6 | "*.tcc": "cpp",
7 | "bitset": "cpp",
8 | "cctype": "cpp",
9 | "chrono": "cpp",
10 | "clocale": "cpp",
11 | "cmath": "cpp",
12 | "condition_variable": "cpp",
13 | "cstdarg": "cpp",
14 | "cstddef": "cpp",
15 | "cstdint": "cpp",
16 | "cstdio": "cpp",
17 | "cstdlib": "cpp",
18 | "cstring": "cpp",
19 | "ctime": "cpp",
20 | "cwchar": "cpp",
21 | "cwctype": "cpp",
22 | "deque": "cpp",
23 | "forward_list": "cpp",
24 | "list": "cpp",
25 | "map": "cpp",
26 | "unordered_map": "cpp",
27 | "unordered_set": "cpp",
28 | "vector": "cpp",
29 | "exception": "cpp",
30 | "algorithm": "cpp",
31 | "buffer": "cpp",
32 | "executor": "cpp",
33 | "functional": "cpp",
34 | "internet": "cpp",
35 | "io_context": "cpp",
36 | "iterator": "cpp",
37 | "memory": "cpp",
38 | "memory_resource": "cpp",
39 | "netfwd": "cpp",
40 | "numeric": "cpp",
41 | "optional": "cpp",
42 | "random": "cpp",
43 | "ratio": "cpp",
44 | "regex": "cpp",
45 | "socket": "cpp",
46 | "string": "cpp",
47 | "string_view": "cpp",
48 | "system_error": "cpp",
49 | "timer": "cpp",
50 | "tuple": "cpp",
51 | "type_traits": "cpp",
52 | "utility": "cpp",
53 | "fstream": "cpp",
54 | "future": "cpp",
55 | "initializer_list": "cpp",
56 | "iomanip": "cpp",
57 | "iosfwd": "cpp",
58 | "iostream": "cpp",
59 | "istream": "cpp",
60 | "limits": "cpp",
61 | "mutex": "cpp",
62 | "new": "cpp",
63 | "ostream": "cpp",
64 | "shared_mutex": "cpp",
65 | "sstream": "cpp",
66 | "stdexcept": "cpp",
67 | "streambuf": "cpp",
68 | "thread": "cpp",
69 | "cinttypes": "cpp",
70 | "typeinfo": "cpp",
71 | "csignal": "cpp",
72 | "set": "cpp",
73 | "valarray": "cpp",
74 | "variant": "cpp"
75 | }
76 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=733558
3 | // for the documentation about the tasks.json format
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "label": "buildProverServer",
8 | "type": "shell",
9 | "command": "npx task buildProverServer /home/jordi/circuits/tools/rollup-376-32-256-64/circuit-376-32-256-64.cpp",
10 | "group": {
11 | "kind": "build",
12 | "isDefault": true
13 | },
14 | "presentation": {
15 | "reveal": "always",
16 | "panel": "new"
17 | },
18 | "problemMatcher": {
19 | "owner": "cpp",
20 | "fileLocation": [
21 | "relative",
22 | "${workspaceFolder}/build"
23 | ],
24 | "pattern": [
25 | {
26 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
27 | "file": 1,
28 | "line": 2,
29 | "column": 3,
30 | "severity": 4,
31 | "message": 5
32 | }
33 | ]
34 | }
35 | },
36 | {
37 | "label": "buildProver",
38 | "type": "shell",
39 | "command": "npx task buildProver",
40 | "group": {
41 | "kind": "build",
42 | "isDefault": true
43 | },
44 | "presentation": {
45 | "reveal": "always",
46 | "panel": "new"
47 | },
48 | "problemMatcher": {
49 | "owner": "cpp",
50 | "fileLocation": [
51 | "relative",
52 | "${workspaceFolder}/build"
53 | ],
54 | "pattern": [
55 | {
56 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
57 | "file": 1,
58 | "line": 2,
59 | "column": 3,
60 | "severity": 4,
61 | "message": 5
62 | }
63 | ]
64 | }
65 | },
66 | ]
67 | }
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | include(cmake/platform.cmake)
4 |
5 | set(USE_ASM ON CACHE BOOL "Use asm implementation for Fr and Fq")
6 | set(USE_OPENMP ON CACHE BOOL "Use OpenMP")
7 |
8 | project(rapidsnark LANGUAGES CXX C ASM)
9 |
10 | set(CMAKE_CXX_STANDARD 11)
11 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
12 |
13 | message("BITS_PER_CHUNK=" ${BITS_PER_CHUNK})
14 | message("USE_ASM=" ${USE_ASM})
15 | message("USE_OPENMP=" ${USE_OPENMP})
16 | message("CMAKE_CROSSCOMPILING=" ${CMAKE_CROSSCOMPILING})
17 |
18 | message("GMP_PREFIX=" ${GMP_PREFIX})
19 | message("GMP_INCLUDE_DIR=" ${GMP_INCLUDE_DIR})
20 | message("GMP_LIB_DIR=" ${GMP_LIB_DIR})
21 |
22 | if (NOT EXISTS ${GMP_INCLUDE_FILE_FULLPATH})
23 | message("WARNING: ${GMP_INCLUDE_FILE_FULLPATH} is not found and so system ${GMP_INCLUDE_FILE} is used.")
24 | endif()
25 |
26 | if (NOT EXISTS ${GMP_LIB_FILE_FULLPATH})
27 | message("WARNING: ${GMP_LIB_FILE_FULLPATH} is not found and so system ${GMP_LIB_FILE} is used.")
28 | set(GMP_LIB gmp)
29 | endif()
30 |
31 |
32 | include_directories(BEFORE ${GMP_INCLUDE_DIR})
33 |
34 |
35 | if(USE_OPENMP)
36 | find_package(OpenMP)
37 |
38 | if(OpenMP_CXX_FOUND)
39 | if(TARGET_PLATFORM MATCHES "android")
40 | message("OpenMP is used")
41 |
42 | elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
43 | message("OpenMP is used")
44 |
45 | else()
46 | set(OpenMP_CXX_FOUND FALSE)
47 | message("OpenMP is not used")
48 |
49 | endif()
50 | endif()
51 | endif()
52 |
53 |
54 | add_subdirectory(src)
55 |
56 |
57 | install(TARGETS prover verifier rapidsnark rapidsnarkStatic rapidsnarkStaticFrFq test_prover fr fq
58 | RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
59 | BUNDLE DESTINATION ${CMAKE_INSTALL_PREFIX}/app
60 | LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
61 |
62 | install(FILES "${GMP_LIB_DIR}/${GMP_LIB_FILE}"
63 | DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
64 |
65 | install(FILES src/prover.h src/verifier.h
66 | DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
67 |
68 | enable_testing()
69 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | ###
2 |
3 | #Build targets
4 | host:
5 | rm -rf build_prover && mkdir build_prover && cd build_prover && \
6 | cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package && \
7 | make -j$(nproc) -vvv && make install
8 |
9 | host_noasm:
10 | rm -rf build_prover_noasm && mkdir build_prover_noasm && cd build_prover_noasm && \
11 | cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_noasm -DUSE_ASM=NO && \
12 | make -j$(nproc) -vvv && make install
13 |
14 | host_arm64:
15 | rm -rf build_prover_arm64 && mkdir build_prover_arm64 && cd build_prover_arm64 && \
16 | cmake .. -DTARGET_PLATFORM=aarch64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_arm64 && \
17 | make -j$(nproc) -vvv && make install
18 |
19 | android:
20 | rm -rf build_prover_android && mkdir build_prover_android && cd build_prover_android && \
21 | cmake .. -DTARGET_PLATFORM=ANDROID -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android -DBUILD_TESTS=OFF -DUSE_OPENMP=OFF && \
22 | make -j$(nproc) -vvv && make install
23 |
24 | android_openmp:
25 | rm -rf build_prover_android_openmp && mkdir build_prover_android_openmp && cd build_prover_android_openmp && \
26 | cmake .. -DTARGET_PLATFORM=ANDROID -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_openmp -DBUILD_TESTS=OFF -DUSE_OPENMP=ON && \
27 | make -j$(nproc) -vvv && make install
28 |
29 | android_x86_64:
30 | rm -rf build_prover_android_x86_64 && mkdir build_prover_android_x86_64 && cd build_prover_android_x86_64 && \
31 | cmake .. -DTARGET_PLATFORM=ANDROID_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_x86_64 -DBUILD_TESTS=OFF -DUSE_OPENMP=OFF && \
32 | make -j$(nproc) -vvv && make install
33 |
34 | android_openmp_x86_64:
35 | rm -rf build_prover_android_openmp_x86_64 && mkdir build_prover_android_openmp_x86_64 && cd build_prover_android_openmp_x86_64 && \
36 | cmake .. -DTARGET_PLATFORM=ANDROID_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_openmp_x86_64 -DBUILD_TESTS=OFF -DUSE_OPENMP=ON && \
37 | make -j$(nproc) -vvv && make install
38 |
39 | ios:
40 | @if [ ! -d "./depends/gmp/package_ios_arm64" ]; then echo "Looks like gmp lib is not built. Run './build_gmp.sh ios' first." && exit 1; fi
41 | rm -rf build_prover_ios && mkdir build_prover_ios && cd build_prover_ios && \
42 | cmake .. -GXcode -DTARGET_PLATFORM=IOS -DCMAKE_INSTALL_PREFIX=../package_ios && \
43 | xcodebuild -destination 'generic/platform=iOS' -scheme rapidsnarkStatic -project rapidsnark.xcodeproj -configuration Release && \
44 | xcodebuild -destination 'generic/platform=iOS' -scheme rapidsnark -project rapidsnark.xcodeproj -configuration Release CODE_SIGNING_ALLOWED=NO && \
45 | cp ../depends/gmp/package_ios_arm64/lib/libgmp.a src/Release-iphoneos && \
46 | echo "" && echo "iOS Simulator artifacts built in build_prover_ios/src/Release-iphoneos" && echo ""
47 |
48 | ios_simulator:
49 | @if [ ! -d "./depends/gmp/package_iphone_simulator" ]; then echo "Looks like gmp lib is not built. Run './build_gmp.sh ios_simulator' first." && exit 1; fi
50 | rm -rf build_prover_ios_simulator && mkdir build_prover_ios_simulator && cd build_prover_ios_simulator && \
51 | cmake .. -GXcode -DTARGET_PLATFORM=IOS_SIMULATOR -DCMAKE_INSTALL_PREFIX=../package_ios_simulator -DUSE_ASM=NO && \
52 | xcodebuild -destination 'generic/platform=iOS Simulator' -scheme rapidsnarkStatic -project rapidsnark.xcodeproj && \
53 | xcodebuild -destination 'generic/platform=iOS Simulator' -scheme rapidsnark -project rapidsnark.xcodeproj CODE_SIGNING_ALLOWED=NO ARCHS=arm64 && \
54 | cp ../depends/gmp/package_iphone_simulator/lib/libgmp.a src/Debug-iphonesimulator && \
55 | echo "" && echo "iOS Simulator artifacts built in build_prover_ios_simulator/src/Debug-iphonesimulator" && echo ""
56 |
57 | macos_arm64:
58 | @if [ ! -d "./depends/gmp/package_macos_arm64" ]; then echo "Looks like gmp lib is not built. Run './build_gmp.sh macos_arm64' first." && exit 1; fi
59 | rm -rf build_prover_macos_arm64 && mkdir build_prover_macos_arm64 && cd build_prover_macos_arm64 && \
60 | cmake .. -DTARGET_PLATFORM=macos_arm64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_macos_arm64 && \
61 | make -j$(nproc) -vvv && make install
62 |
63 | macos_x86_64:
64 | @if [ ! -d "./depends/gmp/package_macos_x86_64" ]; then echo "Looks like gmp lib is not built. Run './build_gmp.sh macos_x86_64' first." && exit 1; fi
65 | rm -rf build_prover_macos_x86_64 && mkdir build_prover_macos_x86_64 && cd build_prover_macos_x86_64 && \
66 | cmake .. -DTARGET_PLATFORM=macos_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_macos_x86_64 && \
67 | make -j$(nproc) -vvv && make install
68 |
69 | clean:
70 | rm -rf build_prover \
71 | build_prover_macos_arm64 \
72 | build_prover_macos_x86_64 \
73 | build_prover_android \
74 | build_prover_android_x86_64 \
75 | build_prover_ios \
76 | build_prover_ios_simulator \
77 | package \
78 | package_macos_arm64 \
79 | package_macos_x86_64 \
80 | package_android \
81 | package_android_x86_64 \
82 | package_ios \
83 | package_ios_simulator \
84 | depends/gmp/package \
85 | depends/gmp/package_macos_arm64 \
86 | depends/gmp/package_macos_x86_64 \
87 | depends/gmp/package_android_arm64 \
88 | depends/gmp/package_android_x86_64 \
89 | depends/gmp/package_ios_arm64 \
90 | depends/gmp/package_iphone_simulator
91 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Important note
2 |
3 | **This is a new implementation of rapidsnark. The original (and now obsoleted) implemenation is available here: [rapidsnark-old](https://github.com/iden3/rapidsnark-old).**
4 |
5 | # rapidsnark
6 |
7 | Rapidsnark is a zkSnark proof generation written in C++ and intel/arm assembly. That generates proofs created in [circom](https://github.com/iden3/circom) and [snarkjs](https://github.com/iden3/snarkjs) very fast.
8 |
9 | ## Dependencies
10 |
11 | You should have installed gcc, cmake, libsodium, and gmp (development)
12 |
13 | In ubuntu:
14 |
15 | ```
16 | sudo apt-get install build-essential cmake libgmp-dev libsodium-dev nasm curl m4
17 | ```
18 |
19 | On MacOS:
20 |
21 | ```
22 | brew install cmake gmp libsodium nasm
23 | ```
24 |
25 | ## Compile prover in standalone mode
26 |
27 | ### Compile prover for x86_64 host machine
28 |
29 | ```sh
30 | git submodule init
31 | git submodule update
32 | ./build_gmp.sh host
33 | make host
34 | ```
35 |
36 | ### Compile prover for macOS arm64 host machine
37 |
38 | ```sh
39 | git submodule init
40 | git submodule update
41 | ./build_gmp.sh macos_arm64
42 | make macos_arm64
43 | ```
44 |
45 | ### Compile prover for linux arm64 host machine
46 |
47 | ```sh
48 | git submodule init
49 | git submodule update
50 | ./build_gmp.sh host
51 | make host_arm64
52 | ```
53 |
54 | ### Compile prover for linux arm64 machine
55 |
56 | ```sh
57 | git submodule init
58 | git submodule update
59 | ./build_gmp.sh host
60 | make arm64
61 | ```
62 |
63 | ### Compile prover for Android
64 |
65 | Install Android NDK from https://developer.android.com/ndk or with help of "SDK Manager" in Android Studio.
66 |
67 | Set the value of ANDROID_NDK environment variable to the absolute path of Android NDK root directory.
68 |
69 | Examples:
70 |
71 | ```sh
72 | export ANDROID_NDK=/home/test/Android/Sdk/ndk/23.1.7779620 # NDK is installed by "SDK Manager" in Android Studio.
73 | export ANDROID_NDK=/home/test/android-ndk-r23b # NDK is installed as a stand-alone package.
74 | ```
75 |
76 | Prerequisites if build on Ubuntu:
77 |
78 | ```sh
79 | apt-get install curl xz-utils build-essential cmake m4 nasm
80 | ```
81 |
82 | Compilation:
83 |
84 | ```sh
85 | git submodule init
86 | git submodule update
87 | ./build_gmp.sh android
88 | make android
89 | ```
90 |
91 | ### Compile prover for iOS
92 |
93 | Install Xcode
94 |
95 | ```sh
96 | git submodule init
97 | git submodule update
98 | ./build_gmp.sh ios
99 | make ios
100 | ```
101 | Open generated Xcode project and compile prover.
102 |
103 | ## Build for iOS emulator
104 |
105 | Install Xcode
106 |
107 | ```sh
108 | git submodule init
109 | git submodule update
110 | ./build_gmp.sh ios_simulator
111 | make ios_simulator
112 | ```
113 |
114 | Files that you need to copy to your XCode project to link against Rapidsnark:
115 | * build_prover_ios_simulator/src/Debug-iphonesimulator/librapidsnark.a
116 | * build_prover_ios_simulator/src/Debug-iphonesimulator/libfq.a
117 | * build_prover_ios_simulator/src/Debug-iphonesimulator/libfr.a
118 | * depends/gmp/package_iphone_simulator/lib/libgmp.a
119 |
120 | ## Building proof
121 |
122 | You have a full prover compiled in the build directory.
123 |
124 | So you can replace snarkjs command:
125 |
126 | ```sh
127 | snarkjs groth16 prove
128 | ```
129 |
130 | by this one
131 | ```sh
132 | ./package/bin/prover
133 | ```
134 |
135 | ## Compile prover in server mode
136 |
137 | ```sh
138 | npm install
139 | git submodule init
140 | git submodule update
141 | npx task buildPistache
142 | npx task buildProverServer
143 | ```
144 |
145 | ## Launch prover in server mode
146 | ```sh
147 | ./build/proverServer ...
148 | ```
149 |
150 | For every `circuit.circom` you have to generate with circom with --c option the `circuit_cpp` and after compilation you have to copy the executable into the `build` folder so the server can generate the witness and then the proof based on this witness.
151 | You have an example of the usage calling the server endpoints to generate the proof with Nodejs in `/tools/request.js`.
152 |
153 | To test a request you should pass an `input.json` as a parameter to the request call.
154 | ```sh
155 | node tools/request.js
156 | ```
157 |
158 | ## Wrappers
159 |
160 | Rapidsnark can be used with several programming languages and environments through wrappers that provide integration with the original library. Below is a list of available wrappers:
161 |
162 | | Wrapper | Repository Link |
163 | | ------------ |-----------------------------------------|
164 | | Go | https://github.com/iden3/go-rapidsnark |
165 | | iOS | https://github.com/iden3/ios-rapidsnark |
166 | | Android | https://github.com/iden3/android-rapidsnark |
167 | | React Native | https://github.com/iden3/react-native-rapidsnark |
168 | | Flutter | https://github.com/iden3/flutter-rapidsnark |
169 |
170 | ## Benchmark
171 |
172 | This prover parallelizes as much as it can the proof generation.
173 |
174 | The prover is much faster that snarkjs and faster than bellman.
175 |
176 | [TODO] Some comparative tests should be done.
177 |
178 | ## Run tests
179 |
180 | You need to perform all the steps from the
181 | [Compile prover in standalone mode](#compile-prover-in-standalone-mode) section.
182 | After that you can run tests with the following command from the build
183 | directory:
184 |
185 | ```sh
186 | # Make sure you are in the build directory
187 | # ./build_prover for linux, ./build_prover_macos_arm64 for macOS.
188 | cmake --build . --parallel && ctest --rerun-failed --output-on-failure
189 | ```
190 |
191 | To run just the `test_public_size` test for custom zkey to measure the
192 | performance, you can run the following command from the build directory:
193 |
194 | ```sh
195 | src/test_public_size ../testdata/circuit_final.zkey 86
196 | ```
197 |
198 | ## License
199 |
200 | rapidsnark is part of the iden3 project copyright 2021 0KIMS association and published with LGPL-3 license. Please check the COPYING file for more details.
201 |
--------------------------------------------------------------------------------
/build/fq.cpp:
--------------------------------------------------------------------------------
1 | #include "fq.hpp"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 |
9 | static mpz_t q;
10 | static mpz_t zero;
11 | static mpz_t one;
12 | static mpz_t mask;
13 | static size_t nBits;
14 | static bool initialized = false;
15 |
16 | void Fq_toMpz(mpz_t r, PFqElement pE) {
17 | FqElement tmp;
18 | Fq_toNormal(&tmp, pE);
19 | if (!(tmp.type & Fq_LONG)) {
20 | mpz_set_si(r, tmp.shortVal);
21 | if (tmp.shortVal<0) {
22 | mpz_add(r, r, q);
23 | }
24 | } else {
25 | mpz_import(r, Fq_N64, -1, 8, -1, 0, (const void *)tmp.longVal);
26 | }
27 | }
28 |
29 | void Fq_fromMpz(PFqElement pE, mpz_t v) {
30 | if (mpz_fits_sint_p(v)) {
31 | pE->type = Fq_SHORT;
32 | pE->shortVal = mpz_get_si(v);
33 | } else {
34 | pE->type = Fq_LONG;
35 | for (int i=0; ilongVal[i] = 0;
36 | mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
37 | }
38 | }
39 |
40 |
41 | bool Fq_init() {
42 | if (initialized) return false;
43 | initialized = true;
44 | mpz_init(q);
45 | mpz_import(q, Fq_N64, -1, 8, -1, 0, (const void *)Fq_q.longVal);
46 | mpz_init_set_ui(zero, 0);
47 | mpz_init_set_ui(one, 1);
48 | nBits = mpz_sizeinbase (q, 2);
49 | mpz_init(mask);
50 | mpz_mul_2exp(mask, one, nBits);
51 | mpz_sub(mask, mask, one);
52 | return true;
53 | }
54 |
55 | void Fq_str2element(PFqElement pE, char const *s, uint base) {
56 | mpz_t mr;
57 | mpz_init_set_str(mr, s, base);
58 | mpz_fdiv_r(mr, mr, q);
59 | Fq_fromMpz(pE, mr);
60 | mpz_clear(mr);
61 | }
62 |
63 | char *Fq_element2str(PFqElement pE) {
64 | FqElement tmp;
65 | mpz_t r;
66 | if (!(pE->type & Fq_LONG)) {
67 | if (pE->shortVal>=0) {
68 | char *r = new char[32];
69 | sprintf(r, "%d", pE->shortVal);
70 | return r;
71 | } else {
72 | mpz_init_set_si(r, pE->shortVal);
73 | mpz_add(r, r, q);
74 | }
75 | } else {
76 | Fq_toNormal(&tmp, pE);
77 | mpz_init(r);
78 | mpz_import(r, Fq_N64, -1, 8, -1, 0, (const void *)tmp.longVal);
79 | }
80 | char *res = mpz_get_str (0, 10, r);
81 | mpz_clear(r);
82 | return res;
83 | }
84 |
85 | void Fq_idiv(PFqElement r, PFqElement a, PFqElement b) {
86 | mpz_t ma;
87 | mpz_t mb;
88 | mpz_t mr;
89 | mpz_init(ma);
90 | mpz_init(mb);
91 | mpz_init(mr);
92 |
93 | Fq_toMpz(ma, a);
94 | // char *s1 = mpz_get_str (0, 10, ma);
95 | // printf("s1 %s\n", s1);
96 | Fq_toMpz(mb, b);
97 | // char *s2 = mpz_get_str (0, 10, mb);
98 | // printf("s2 %s\n", s2);
99 | mpz_fdiv_q(mr, ma, mb);
100 | // char *sr = mpz_get_str (0, 10, mr);
101 | // printf("r %s\n", sr);
102 | Fq_fromMpz(r, mr);
103 |
104 | mpz_clear(ma);
105 | mpz_clear(mb);
106 | mpz_clear(mr);
107 | }
108 |
109 | void Fq_mod(PFqElement r, PFqElement a, PFqElement b) {
110 | mpz_t ma;
111 | mpz_t mb;
112 | mpz_t mr;
113 | mpz_init(ma);
114 | mpz_init(mb);
115 | mpz_init(mr);
116 |
117 | Fq_toMpz(ma, a);
118 | Fq_toMpz(mb, b);
119 | mpz_fdiv_r(mr, ma, mb);
120 | Fq_fromMpz(r, mr);
121 |
122 | mpz_clear(ma);
123 | mpz_clear(mb);
124 | mpz_clear(mr);
125 | }
126 |
127 | void Fq_pow(PFqElement r, PFqElement a, PFqElement b) {
128 | mpz_t ma;
129 | mpz_t mb;
130 | mpz_t mr;
131 | mpz_init(ma);
132 | mpz_init(mb);
133 | mpz_init(mr);
134 |
135 | Fq_toMpz(ma, a);
136 | Fq_toMpz(mb, b);
137 | mpz_powm(mr, ma, mb, q);
138 | Fq_fromMpz(r, mr);
139 |
140 | mpz_clear(ma);
141 | mpz_clear(mb);
142 | mpz_clear(mr);
143 | }
144 |
145 | void Fq_inv(PFqElement r, PFqElement a) {
146 | mpz_t ma;
147 | mpz_t mr;
148 | mpz_init(ma);
149 | mpz_init(mr);
150 |
151 | Fq_toMpz(ma, a);
152 | mpz_invert(mr, ma, q);
153 | Fq_fromMpz(r, mr);
154 | mpz_clear(ma);
155 | mpz_clear(mr);
156 | }
157 |
158 | void Fq_div(PFqElement r, PFqElement a, PFqElement b) {
159 | FqElement tmp;
160 | Fq_inv(&tmp, b);
161 | Fq_mul(r, a, &tmp);
162 | }
163 |
164 | void Fq_fail() {
165 | throw std::runtime_error("Fq error");
166 | }
167 |
168 | void Fq_longErr()
169 | {
170 | Fq_fail();
171 | }
172 |
173 | RawFq::RawFq() {
174 | Fq_init();
175 | set(fZero, 0);
176 | set(fOne, 1);
177 | neg(fNegOne, fOne);
178 | }
179 |
180 | RawFq::~RawFq() {
181 | }
182 |
183 | void RawFq::fromString(Element &r, const std::string &s, uint32_t radix) {
184 | mpz_t mr;
185 | mpz_init_set_str(mr, s.c_str(), radix);
186 | mpz_fdiv_r(mr, mr, q);
187 | for (int i=0; i>3] & (1 << (p & 0x7)))
259 | void RawFq::exp(Element &r, const Element &base, uint8_t* scalar, unsigned int scalarSize) {
260 | bool oneFound = false;
261 | Element copyBase;
262 | copy(copyBase, base);
263 | for (int i=scalarSize*8-1; i>=0; i--) {
264 | if (!oneFound) {
265 | if ( !BIT_IS_SET(scalar, i) ) continue;
266 | copy(r, copyBase);
267 | oneFound = true;
268 | continue;
269 | }
270 | square(r, r);
271 | if ( BIT_IS_SET(scalar, i) ) {
272 | mul(r, r, copyBase);
273 | }
274 | }
275 | if (!oneFound) {
276 | copy(r, fOne);
277 | }
278 | }
279 |
280 | void RawFq::toMpz(mpz_t r, const Element &a) {
281 | Element tmp;
282 | Fq_rawFromMontgomery(tmp.v, a.v);
283 | mpz_import(r, Fq_N64, -1, 8, -1, 0, (const void *)tmp.v);
284 | }
285 |
286 | void RawFq::fromMpz(Element &r, const mpz_t a) {
287 | for (int i=0; i
6 | #include
7 | #include
8 |
9 | #ifdef __APPLE__
10 | #include // typedef unsigned int uint;
11 | #endif // __APPLE__
12 |
13 | extern FqElement Fq_q;
14 | extern FqElement Fq_R2;
15 | extern FqElement Fq_R3;
16 | extern FqRawElement Fq_rawq;
17 | extern FqRawElement Fq_rawR3;
18 |
19 | #ifdef USE_ASM
20 |
21 | #if defined(ARCH_X86_64)
22 |
23 | extern "C" void Fq_copy(PFqElement r, PFqElement a);
24 | extern "C" void Fq_copyn(PFqElement r, PFqElement a, int n);
25 | extern "C" void Fq_add(PFqElement r, PFqElement a, PFqElement b);
26 | extern "C" void Fq_sub(PFqElement r, PFqElement a, PFqElement b);
27 | extern "C" void Fq_neg(PFqElement r, PFqElement a);
28 | extern "C" void Fq_mul(PFqElement r, PFqElement a, PFqElement b);
29 | extern "C" void Fq_square(PFqElement r, PFqElement a);
30 | extern "C" void Fq_band(PFqElement r, PFqElement a, PFqElement b);
31 | extern "C" void Fq_bor(PFqElement r, PFqElement a, PFqElement b);
32 | extern "C" void Fq_bxor(PFqElement r, PFqElement a, PFqElement b);
33 | extern "C" void Fq_bnot(PFqElement r, PFqElement a);
34 | extern "C" void Fq_shl(PFqElement r, PFqElement a, PFqElement b);
35 | extern "C" void Fq_shr(PFqElement r, PFqElement a, PFqElement b);
36 | extern "C" void Fq_eq(PFqElement r, PFqElement a, PFqElement b);
37 | extern "C" void Fq_neq(PFqElement r, PFqElement a, PFqElement b);
38 | extern "C" void Fq_lt(PFqElement r, PFqElement a, PFqElement b);
39 | extern "C" void Fq_gt(PFqElement r, PFqElement a, PFqElement b);
40 | extern "C" void Fq_leq(PFqElement r, PFqElement a, PFqElement b);
41 | extern "C" void Fq_geq(PFqElement r, PFqElement a, PFqElement b);
42 | extern "C" void Fq_land(PFqElement r, PFqElement a, PFqElement b);
43 | extern "C" void Fq_lor(PFqElement r, PFqElement a, PFqElement b);
44 | extern "C" void Fq_lnot(PFqElement r, PFqElement a);
45 | extern "C" void Fq_toNormal(PFqElement r, PFqElement a);
46 | extern "C" void Fq_toLongNormal(PFqElement r, PFqElement a);
47 | extern "C" void Fq_toMontgomery(PFqElement r, PFqElement a);
48 |
49 | extern "C" int Fq_isTrue(PFqElement pE);
50 | extern "C" int Fq_toInt(PFqElement pE);
51 |
52 | extern "C" void Fq_rawCopy(FqRawElement pRawResult, const FqRawElement pRawA);
53 | extern "C" void Fq_rawSwap(FqRawElement pRawResult, FqRawElement pRawA);
54 | extern "C" void Fq_rawAdd(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
55 | extern "C" void Fq_rawSub(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
56 | extern "C" void Fq_rawNeg(FqRawElement pRawResult, const FqRawElement pRawA);
57 | extern "C" void Fq_rawMMul(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
58 | extern "C" void Fq_rawMSquare(FqRawElement pRawResult, const FqRawElement pRawA);
59 | extern "C" void Fq_rawMMul1(FqRawElement pRawResult, const FqRawElement pRawA, uint64_t pRawB);
60 | extern "C" void Fq_rawToMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA);
61 | extern "C" void Fq_rawFromMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA);
62 | extern "C" int Fq_rawIsEq(const FqRawElement pRawA, const FqRawElement pRawB);
63 | extern "C" int Fq_rawIsZero(const FqRawElement pRawB);
64 | extern "C" void Fq_rawShl(FqRawElement r, FqRawElement a, uint64_t b);
65 | extern "C" void Fq_rawShr(FqRawElement r, FqRawElement a, uint64_t b);
66 |
67 | extern "C" void Fq_fail();
68 |
69 | #elif defined(ARCH_ARM64)
70 |
71 | void Fq_copy(PFqElement r, PFqElement a);
72 | void Fq_mul(PFqElement r, PFqElement a, PFqElement b);
73 | void Fq_toNormal(PFqElement r, PFqElement a);
74 |
75 | void Fq_toLongNormal(PFqElement r, PFqElement a);
76 | int Fq_isTrue(PFqElement pE);
77 | void Fq_copyn(PFqElement r, PFqElement a, int n);
78 | void Fq_lt(PFqElement r, PFqElement a, PFqElement b);
79 | int Fq_toInt(PFqElement pE);
80 | void Fq_shr(PFqElement r, PFqElement a, PFqElement b);
81 | void Fq_shl(PFqElement r, PFqElement a, PFqElement b);
82 | void Fq_band(PFqElement r, PFqElement a, PFqElement b);
83 | void Fq_bor(PFqElement r, PFqElement a, PFqElement b);
84 | void Fq_bxor(PFqElement r, PFqElement a, PFqElement b);
85 | void Fq_bnot(PFqElement r, PFqElement a);
86 | void Fq_sub(PFqElement r, PFqElement a, PFqElement b);
87 | void Fq_eq(PFqElement r, PFqElement a, PFqElement b);
88 | void Fq_neq(PFqElement r, PFqElement a, PFqElement b);
89 | void Fq_add(PFqElement r, PFqElement a, PFqElement b);
90 | void Fq_gt(PFqElement r, PFqElement a, PFqElement b);
91 | void Fq_leq(PFqElement r, PFqElement a, PFqElement b);
92 | void Fq_geq(PFqElement r, PFqElement a, PFqElement b);
93 | void Fq_lor(PFqElement r, PFqElement a, PFqElement b);
94 | void Fq_lnot(PFqElement r, PFqElement a);
95 | void Fq_land(PFqElement r, PFqElement a, PFqElement b);
96 | void Fq_neg(PFqElement r, PFqElement a);
97 | void Fq_toMontgomery(PFqElement r, PFqElement a);
98 | void Fq_square(PFqElement r, PFqElement a);
99 |
100 | extern "C" void Fq_rawCopy(FqRawElement pRawResult, const FqRawElement pRawA);
101 | extern "C" void Fq_rawSwap(FqRawElement pRawResult, FqRawElement pRawA);
102 | extern "C" void Fq_rawAdd(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
103 | extern "C" void Fq_rawSub(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
104 | extern "C" void Fq_rawNeg(FqRawElement pRawResult, const FqRawElement pRawA);
105 | extern "C" void Fq_rawMMul(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
106 | void Fq_rawMSquare(FqRawElement pRawResult, const FqRawElement pRawA);
107 | extern "C" void Fq_rawMMul1(FqRawElement pRawResult, const FqRawElement pRawA, uint64_t pRawB);
108 | void Fq_rawToMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA);
109 | extern "C" void Fq_rawFromMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA);
110 | extern "C" int Fq_rawIsEq(const FqRawElement pRawA, const FqRawElement pRawB);
111 | extern "C" int Fq_rawIsZero(const FqRawElement pRawB);
112 | void Fq_rawZero(FqRawElement pRawResult);
113 | extern "C" void Fq_rawCopyS2L(FqRawElement pRawResult, int64_t val);
114 | extern "C" void Fq_rawAddLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB);
115 | extern "C" void Fq_rawSubSL(FqRawElement pRawResult, uint64_t rawA, FqRawElement pRawB);
116 | extern "C" void Fq_rawSubLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB);
117 | extern "C" void Fq_rawNegLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB);
118 | extern "C" int Fq_rawCmp(FqRawElement pRawA, FqRawElement pRawB);
119 | extern "C" void Fq_rawAnd(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
120 | extern "C" void Fq_rawOr(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
121 | extern "C" void Fq_rawXor(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
122 | extern "C" void Fq_rawShl(FqRawElement r, FqRawElement a, uint64_t b);
123 | extern "C" void Fq_rawShr(FqRawElement r, FqRawElement a, uint64_t b);
124 | extern "C" void Fq_rawNot(FqRawElement pRawResult, FqRawElement pRawA);
125 | extern "C" void Fq_rawSubRegular(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
126 |
127 | void Fq_fail();
128 | void Fq_longErr();
129 |
130 | #endif
131 |
132 | #else
133 |
134 |
135 | void Fq_copy(PFqElement r, PFqElement a);
136 | void Fq_mul(PFqElement r, PFqElement a, PFqElement b);
137 | void Fq_toNormal(PFqElement r, PFqElement a);
138 |
139 | void Fq_toLongNormal(PFqElement r, PFqElement a);
140 | int Fq_isTrue(PFqElement pE);
141 | void Fq_copyn(PFqElement r, PFqElement a, int n);
142 | void Fq_lt(PFqElement r, PFqElement a, PFqElement b);
143 | int Fq_toInt(PFqElement pE);
144 | void Fq_shl(PFqElement r, PFqElement a, PFqElement b);
145 | void Fq_shr(PFqElement r, PFqElement a, PFqElement b);
146 | void Fq_band(PFqElement r, PFqElement a, PFqElement b);
147 | void Fq_bor(PFqElement r, PFqElement a, PFqElement b);
148 | void Fq_bxor(PFqElement r, PFqElement a, PFqElement b);
149 | void Fq_bnot(PFqElement r, PFqElement a);
150 | void Fq_sub(PFqElement r, PFqElement a, PFqElement b);
151 | void Fq_eq(PFqElement r, PFqElement a, PFqElement b);
152 | void Fq_neq(PFqElement r, PFqElement a, PFqElement b);
153 | void Fq_add(PFqElement r, PFqElement a, PFqElement b);
154 | void Fq_gt(PFqElement r, PFqElement a, PFqElement b);
155 | void Fq_leq(PFqElement r, PFqElement a, PFqElement b);
156 | void Fq_geq(PFqElement r, PFqElement a, PFqElement b);
157 | void Fq_lor(PFqElement r, PFqElement a, PFqElement b);
158 | void Fq_lnot(PFqElement r, PFqElement a);
159 | void Fq_land(PFqElement r, PFqElement a, PFqElement b);
160 | void Fq_neg(PFqElement r, PFqElement a);
161 | void Fq_toMontgomery(PFqElement r, PFqElement a);
162 | void Fq_square(PFqElement r, PFqElement a);
163 |
164 | void Fq_rawCopy(FqRawElement pRawResult, const FqRawElement pRawA);
165 | void Fq_rawSwap(FqRawElement pRawResult, FqRawElement pRawA);
166 | void Fq_rawAdd(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
167 | void Fq_rawSub(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
168 | void Fq_rawNeg(FqRawElement pRawResult, const FqRawElement pRawA);
169 | void Fq_rawMMul(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB);
170 | void Fq_rawMSquare(FqRawElement pRawResult, const FqRawElement pRawA);
171 | void Fq_rawMMul1(FqRawElement pRawResult, const FqRawElement pRawA, uint64_t pRawB);
172 | void Fq_rawToMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA);
173 | void Fq_rawFromMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA);
174 | int Fq_rawIsEq(const FqRawElement pRawA, const FqRawElement pRawB);
175 | int Fq_rawIsZero(const FqRawElement pRawB);
176 | void Fq_rawZero(FqRawElement pRawResult);
177 | void Fq_rawCopyS2L(FqRawElement pRawResult, int64_t val);
178 | void Fq_rawAddLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB);
179 | void Fq_rawSubSL(FqRawElement pRawResult, uint64_t rawA, FqRawElement pRawB);
180 | void Fq_rawSubLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB);
181 | void Fq_rawNegLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB);
182 | int Fq_rawCmp(FqRawElement pRawA, FqRawElement pRawB);
183 | void Fq_rawAnd(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
184 | void Fq_rawOr(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
185 | void Fq_rawXor(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
186 | void Fq_rawShl(FqRawElement r, FqRawElement a, uint64_t b);
187 | void Fq_rawShr(FqRawElement r, FqRawElement a, uint64_t b);
188 | void Fq_rawNot(FqRawElement pRawResult, FqRawElement pRawA);
189 | void Fq_rawSubRegular(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB);
190 |
191 | void Fq_fail();
192 | void Fq_longErr();
193 |
194 | #endif
195 |
196 | // Pending functions to convert
197 |
198 | void Fq_str2element(PFqElement pE, char const*s, uint base);
199 | char *Fq_element2str(PFqElement pE);
200 | void Fq_idiv(PFqElement r, PFqElement a, PFqElement b);
201 | void Fq_mod(PFqElement r, PFqElement a, PFqElement b);
202 | void Fq_inv(PFqElement r, PFqElement a);
203 | void Fq_div(PFqElement r, PFqElement a, PFqElement b);
204 | void Fq_pow(PFqElement r, PFqElement a, PFqElement b);
205 |
206 | class RawFq {
207 |
208 | public:
209 | const static int N64 = Fq_N64;
210 | const static int MaxBits = 254;
211 |
212 |
213 | struct Element {
214 | FqRawElement v;
215 | };
216 |
217 | private:
218 | Element fZero;
219 | Element fOne;
220 | Element fNegOne;
221 |
222 | public:
223 |
224 | RawFq();
225 | ~RawFq();
226 |
227 | const Element &zero() { return fZero; };
228 | const Element &one() { return fOne; };
229 | const Element &negOne() { return fNegOne; };
230 | Element set(int value);
231 | void set(Element &r, int value);
232 |
233 | void fromString(Element &r, const std::string &n, uint32_t radix = 10);
234 | std::string toString(const Element &a, uint32_t radix = 10);
235 |
236 | void inline copy(Element &r, const Element &a) { Fq_rawCopy(r.v, a.v); };
237 | void inline swap(Element &a, Element &b) { Fq_rawSwap(a.v, b.v); };
238 | void inline add(Element &r, const Element &a, const Element &b) { Fq_rawAdd(r.v, a.v, b.v); };
239 | void inline sub(Element &r, const Element &a, const Element &b) { Fq_rawSub(r.v, a.v, b.v); };
240 | void inline mul(Element &r, const Element &a, const Element &b) { Fq_rawMMul(r.v, a.v, b.v); };
241 |
242 | Element inline add(const Element &a, const Element &b) { Element r; Fq_rawAdd(r.v, a.v, b.v); return r;};
243 | Element inline sub(const Element &a, const Element &b) { Element r; Fq_rawSub(r.v, a.v, b.v); return r;};
244 | Element inline mul(const Element &a, const Element &b) { Element r; Fq_rawMMul(r.v, a.v, b.v); return r;};
245 |
246 | Element inline neg(const Element &a) { Element r; Fq_rawNeg(r.v, a.v); return r; };
247 | Element inline square(const Element &a) { Element r; Fq_rawMSquare(r.v, a.v); return r; };
248 |
249 | Element inline add(int a, const Element &b) { return add(set(a), b);};
250 | Element inline sub(int a, const Element &b) { return sub(set(a), b);};
251 | Element inline mul(int a, const Element &b) { return mul(set(a), b);};
252 |
253 | Element inline add(const Element &a, int b) { return add(a, set(b));};
254 | Element inline sub(const Element &a, int b) { return sub(a, set(b));};
255 | Element inline mul(const Element &a, int b) { return mul(a, set(b));};
256 |
257 | void inline mul1(Element &r, const Element &a, uint64_t b) { Fq_rawMMul1(r.v, a.v, b); };
258 | void inline neg(Element &r, const Element &a) { Fq_rawNeg(r.v, a.v); };
259 | void inline square(Element &r, const Element &a) { Fq_rawMSquare(r.v, a.v); };
260 | void inv(Element &r, const Element &a);
261 | void div(Element &r, const Element &a, const Element &b);
262 | void exp(Element &r, const Element &base, uint8_t* scalar, unsigned int scalarSize);
263 |
264 | void inline toMontgomery(Element &r, const Element &a) { Fq_rawToMontgomery(r.v, a.v); };
265 | void inline fromMontgomery(Element &r, const Element &a) { Fq_rawFromMontgomery(r.v, a.v); };
266 | int inline eq(const Element &a, const Element &b) { return Fq_rawIsEq(a.v, b.v); };
267 | int inline isZero(const Element &a) { return Fq_rawIsZero(a.v); };
268 |
269 | void toMpz(mpz_t r, const Element &a);
270 | void fromMpz(Element &a, const mpz_t r);
271 |
272 | int toRprBE(const Element &element, uint8_t *data, int bytes);
273 | int fromRprBE(Element &element, const uint8_t *data, int bytes);
274 |
275 | int bytes ( void ) { return Fq_N64 * 8; };
276 |
277 | void fromUI(Element &r, unsigned long int v);
278 |
279 | static RawFq field;
280 |
281 | };
282 |
283 |
284 | #endif // __FQ_H
285 |
286 |
287 |
288 |
--------------------------------------------------------------------------------
/build/fq_element.hpp:
--------------------------------------------------------------------------------
1 | #ifndef FQ_ELEMENT_HPP
2 | #define FQ_ELEMENT_HPP
3 |
4 | #include
5 |
6 | #define Fq_N64 4
7 | #define Fq_SHORT 0x00000000
8 | #define Fq_MONTGOMERY 0x40000000
9 | #define Fq_SHORTMONTGOMERY 0x40000000
10 | #define Fq_LONG 0x80000000
11 | #define Fq_LONGMONTGOMERY 0xC0000000
12 |
13 | typedef uint64_t FqRawElement[Fq_N64];
14 |
15 | typedef struct __attribute__((__packed__)) {
16 | int32_t shortVal;
17 | uint32_t type;
18 | FqRawElement longVal;
19 | } FqElement;
20 |
21 | typedef FqElement *PFqElement;
22 |
23 | #endif // FQ_ELEMENT_HPP
24 |
--------------------------------------------------------------------------------
/build/fq_raw_generic.cpp:
--------------------------------------------------------------------------------
1 | #include "fq_element.hpp"
2 | #include
3 | #include
4 |
5 | static uint64_t Fq_rawq[] = {0x3c208c16d87cfd47,0x97816a916871ca8d,0xb85045b68181585d,0x30644e72e131a029, 0};
6 | static FqRawElement Fq_rawR2 = {0xf32cfc5b538afa89,0xb5e71911d44501fb,0x47ab1eff0a417ff6,0x06d89f71cab8351f};
7 | static uint64_t Fq_np = {0x87d20782e4866389};
8 | static uint64_t lboMask = 0x3fffffffffffffff;
9 |
10 |
11 | void Fq_rawAdd(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB)
12 | {
13 | uint64_t carry = mpn_add_n(pRawResult, pRawA, pRawB, Fq_N64);
14 |
15 | if(carry || mpn_cmp(pRawResult, Fq_rawq, Fq_N64) >= 0)
16 | {
17 | mpn_sub_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
18 | }
19 | }
20 |
21 | void Fq_rawAddLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB)
22 | {
23 | uint64_t carry = mpn_add_1(pRawResult, pRawA, Fq_N64, rawB);
24 |
25 | if(carry || mpn_cmp(pRawResult, Fq_rawq, Fq_N64) >= 0)
26 | {
27 | mpn_sub_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
28 | }
29 | }
30 |
31 | void Fq_rawSub(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB)
32 | {
33 | uint64_t carry = mpn_sub_n(pRawResult, pRawA, pRawB, Fq_N64);
34 |
35 | if(carry)
36 | {
37 | mpn_add_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
38 | }
39 | }
40 |
41 | void Fq_rawSubRegular(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB)
42 | {
43 | mpn_sub_n(pRawResult, pRawA, pRawB, Fq_N64);
44 | }
45 |
46 | void Fq_rawSubSL(FqRawElement pRawResult, uint64_t rawA, FqRawElement pRawB)
47 | {
48 | FqRawElement pRawA = {rawA, 0, 0, 0};
49 |
50 | uint64_t carry = mpn_sub_n(pRawResult, pRawA, pRawB, Fq_N64);
51 |
52 | if(carry)
53 | {
54 | mpn_add_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
55 | }
56 | }
57 |
58 | void Fq_rawSubLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB)
59 | {
60 | uint64_t carry = mpn_sub_1(pRawResult, pRawA, Fq_N64, rawB);
61 |
62 | if(carry)
63 | {
64 | mpn_add_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
65 | }
66 | }
67 |
68 | void Fq_rawNeg(FqRawElement pRawResult, const FqRawElement pRawA)
69 | {
70 | const uint64_t zero[Fq_N64] = {0, 0, 0, 0};
71 |
72 | if (mpn_cmp(pRawA, zero, Fq_N64) != 0)
73 | {
74 | mpn_sub_n(pRawResult, Fq_rawq, pRawA, Fq_N64);
75 | }
76 | else
77 | {
78 | mpn_copyi(pRawResult, zero, Fq_N64);
79 | }
80 | }
81 |
82 | // Substracts a long element and a short element form 0
83 | void Fq_rawNegLS(FqRawElement pRawResult, FqRawElement pRawA, uint64_t rawB)
84 | {
85 | uint64_t carry1 = mpn_sub_1(pRawResult, Fq_rawq, Fq_N64, rawB);
86 | uint64_t carry2 = mpn_sub_n(pRawResult, pRawResult, pRawA, Fq_N64);
87 |
88 | if (carry1 || carry2)
89 | {
90 | mpn_add_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
91 | }
92 | }
93 |
94 | void Fq_rawCopy(FqRawElement pRawResult, const FqRawElement pRawA)
95 | {
96 | pRawResult[0] = pRawA[0];
97 | pRawResult[1] = pRawA[1];
98 | pRawResult[2] = pRawA[2];
99 | pRawResult[3] = pRawA[3];
100 | }
101 |
102 | int Fq_rawIsEq(const FqRawElement pRawA, const FqRawElement pRawB)
103 | {
104 | return mpn_cmp(pRawA, pRawB, Fq_N64) == 0;
105 | }
106 |
107 | void Fq_rawMMul(FqRawElement pRawResult, const FqRawElement pRawA, const FqRawElement pRawB)
108 | {
109 | const mp_size_t N = Fq_N64+1;
110 | const uint64_t *mq = Fq_rawq;
111 |
112 | uint64_t np0;
113 |
114 | uint64_t product0[N] = {0};
115 | uint64_t product1[N] = {0};
116 | uint64_t product2[N] = {0};
117 | uint64_t product3[N] = {0};
118 |
119 | product0[4] = mpn_mul_1(product0, pRawB, Fq_N64, pRawA[0]);
120 |
121 | np0 = Fq_np * product0[0];
122 | product1[1] = mpn_addmul_1(product0, mq, N, np0);
123 |
124 | product1[4] = mpn_addmul_1(product1, pRawB, Fq_N64, pRawA[1]);
125 | mpn_add(product1, product1, N, product0+1, N-1);
126 |
127 | np0 = Fq_np * product1[0];
128 | product2[1] = mpn_addmul_1(product1, mq, N, np0);
129 |
130 | product2[4] = mpn_addmul_1(product2, pRawB, Fq_N64, pRawA[2]);
131 | mpn_add(product2, product2, N, product1+1, N-1);
132 |
133 | np0 = Fq_np * product2[0];
134 | product3[1] = mpn_addmul_1(product2, mq, N, np0);
135 |
136 | product3[4] = mpn_addmul_1(product3, pRawB, Fq_N64, pRawA[3]);
137 | mpn_add(product3, product3, N, product2+1, N-1);
138 |
139 | np0 = Fq_np * product3[0];
140 | mpn_addmul_1(product3, mq, N, np0);
141 |
142 | mpn_copyi(pRawResult, product3+1, Fq_N64);
143 |
144 | if (mpn_cmp(pRawResult, mq, Fq_N64) >= 0)
145 | {
146 | mpn_sub_n(pRawResult, pRawResult, mq, Fq_N64);
147 | }
148 | }
149 |
150 | void Fq_rawMSquare(FqRawElement pRawResult, const FqRawElement pRawA)
151 | {
152 | Fq_rawMMul(pRawResult, pRawA, pRawA);
153 | }
154 |
155 | void Fq_rawMMul1(FqRawElement pRawResult, const FqRawElement pRawA, uint64_t pRawB)
156 | {
157 | const mp_size_t N = Fq_N64+1;
158 | const uint64_t *mq = Fq_rawq;
159 |
160 | uint64_t np0;
161 |
162 | uint64_t product0[N] = {0};
163 | uint64_t product1[N] = {0};
164 | uint64_t product2[N] = {0};
165 | uint64_t product3[N] = {0};
166 |
167 | product0[4] = mpn_mul_1(product0, pRawA, Fq_N64, pRawB);
168 |
169 | np0 = Fq_np * product0[0];
170 | product1[1] = mpn_addmul_1(product0, mq, N, np0);
171 | mpn_add(product1, product1, N, product0+1, N-1);
172 |
173 | np0 = Fq_np * product1[0];
174 | product2[1] = mpn_addmul_1(product1, mq, N, np0);
175 | mpn_add(product2, product2, N, product1+1, N-1);
176 |
177 | np0 = Fq_np * product2[0];
178 | product3[1] = mpn_addmul_1(product2, mq, N, np0);
179 | mpn_add(product3, product3, N, product2+1, N-1);
180 |
181 | np0 = Fq_np * product3[0];
182 | mpn_addmul_1(product3, mq, N, np0);
183 |
184 | mpn_copyi(pRawResult, product3+1, Fq_N64);
185 |
186 | if (mpn_cmp(pRawResult, mq, Fq_N64) >= 0)
187 | {
188 | mpn_sub_n(pRawResult, pRawResult, mq, Fq_N64);
189 | }
190 | }
191 |
192 | void Fq_rawToMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA)
193 | {
194 | Fq_rawMMul(pRawResult, pRawA, Fq_rawR2);
195 | }
196 |
197 | void Fq_rawFromMontgomery(FqRawElement pRawResult, const FqRawElement &pRawA)
198 | {
199 | const mp_size_t N = Fq_N64+1;
200 | const uint64_t *mq = Fq_rawq;
201 |
202 | uint64_t np0;
203 |
204 | uint64_t product0[N];
205 | uint64_t product1[N] = {0};
206 | uint64_t product2[N] = {0};
207 | uint64_t product3[N] = {0};
208 |
209 | mpn_copyi(product0, pRawA, Fq_N64); product0[4] = 0;
210 |
211 | np0 = Fq_np * product0[0];
212 | product1[1] = mpn_addmul_1(product0, mq, N, np0);
213 | mpn_add(product1, product1, N, product0+1, N-1);
214 |
215 | np0 = Fq_np * product1[0];
216 | product2[1] = mpn_addmul_1(product1, mq, N, np0);
217 | mpn_add(product2, product2, N, product1+1, N-1);
218 |
219 | np0 = Fq_np * product2[0];
220 | product3[1] = mpn_addmul_1(product2, mq, N, np0);
221 | mpn_add(product3, product3, N, product2+1, N-1);
222 |
223 | np0 = Fq_np * product3[0];
224 | mpn_addmul_1(product3, mq, N, np0);
225 |
226 | mpn_copyi(pRawResult, product3+1, Fq_N64);
227 |
228 | if (mpn_cmp(pRawResult, mq, Fq_N64) >= 0)
229 | {
230 | mpn_sub_n(pRawResult, pRawResult, mq, Fq_N64);
231 | }
232 | }
233 |
234 | int Fq_rawIsZero(const FqRawElement rawA)
235 | {
236 | return mpn_zero_p(rawA, Fq_N64) ? 1 : 0;
237 | }
238 |
239 | int Fq_rawCmp(FqRawElement pRawA, FqRawElement pRawB)
240 | {
241 | return mpn_cmp(pRawA, pRawB, Fq_N64);
242 | }
243 |
244 | void Fq_rawSwap(FqRawElement pRawResult, FqRawElement pRawA)
245 | {
246 | FqRawElement temp;
247 |
248 | temp[0] = pRawResult[0];
249 | temp[1] = pRawResult[1];
250 | temp[2] = pRawResult[2];
251 | temp[3] = pRawResult[3];
252 |
253 | pRawResult[0] = pRawA[0];
254 | pRawResult[1] = pRawA[1];
255 | pRawResult[2] = pRawA[2];
256 | pRawResult[3] = pRawA[3];
257 |
258 | pRawA[0] = temp[0];
259 | pRawA[1] = temp[1];
260 | pRawA[2] = temp[2];
261 | pRawA[3] = temp[3];
262 | }
263 |
264 | void Fq_rawCopyS2L(FqRawElement pRawResult, int64_t val)
265 | {
266 | pRawResult[0] = val;
267 | pRawResult[1] = 0;
268 | pRawResult[2] = 0;
269 | pRawResult[3] = 0;
270 |
271 | if (val < 0)
272 | {
273 | pRawResult[1] = -1;
274 | pRawResult[2] = -1;
275 | pRawResult[3] = -1;
276 |
277 | mpn_add_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
278 | }
279 | }
280 |
281 |
282 | void Fq_rawAnd(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB)
283 | {
284 | mpn_and_n(pRawResult, pRawA, pRawB, Fq_N64);
285 |
286 | pRawResult[3] &= lboMask;
287 |
288 | if (mpn_cmp(pRawResult, Fq_rawq, Fq_N64) >= 0)
289 | {
290 | mpn_sub_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
291 | }
292 | }
293 |
294 | void Fq_rawOr(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB)
295 | {
296 | mpn_ior_n(pRawResult, pRawA, pRawB, Fq_N64);
297 |
298 | pRawResult[3] &= lboMask;
299 |
300 | if (mpn_cmp(pRawResult, Fq_rawq, Fq_N64) >= 0)
301 | {
302 | mpn_sub_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
303 | }
304 | }
305 |
306 | void Fq_rawXor(FqRawElement pRawResult, FqRawElement pRawA, FqRawElement pRawB)
307 | {
308 | mpn_xor_n(pRawResult, pRawA, pRawB, Fq_N64);
309 |
310 | pRawResult[3] &= lboMask;
311 |
312 | if (mpn_cmp(pRawResult, Fq_rawq, Fq_N64) >= 0)
313 | {
314 | mpn_sub_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
315 | }
316 | }
317 |
318 | void Fq_rawShl(FqRawElement r, FqRawElement a, uint64_t b)
319 | {
320 | uint64_t bit_shift = b % 64;
321 | uint64_t word_shift = b / 64;
322 | uint64_t word_count = Fq_N64 - word_shift;
323 |
324 | mpn_copyi(r + word_shift, a, word_count);
325 | std::memset(r, 0, word_shift * sizeof(uint64_t));
326 |
327 | if (bit_shift)
328 | {
329 | mpn_lshift(r, r, Fq_N64, bit_shift);
330 | }
331 |
332 | r[3] &= lboMask;
333 |
334 | if (mpn_cmp(r, Fq_rawq, Fq_N64) >= 0)
335 | {
336 | mpn_sub_n(r, r, Fq_rawq, Fq_N64);
337 | }
338 | }
339 |
340 | void Fq_rawShr(FqRawElement r, FqRawElement a, uint64_t b)
341 | {
342 | const uint64_t bit_shift = b % 64;
343 | const uint64_t word_shift = b / 64;
344 | const uint64_t word_count = Fq_N64 - word_shift;
345 |
346 | mpn_copyi(r, a + word_shift, word_count);
347 | std::memset(r + word_count, 0, word_shift * sizeof(uint64_t));
348 |
349 | if (bit_shift)
350 | {
351 | mpn_rshift(r, r, Fq_N64, bit_shift);
352 | }
353 | }
354 |
355 | void Fq_rawNot(FqRawElement pRawResult, FqRawElement pRawA)
356 | {
357 | mpn_com(pRawResult, pRawA, Fq_N64);
358 |
359 | pRawResult[3] &= lboMask;
360 |
361 | if (mpn_cmp(pRawResult, Fq_rawq, Fq_N64) >= 0)
362 | {
363 | mpn_sub_n(pRawResult, pRawResult, Fq_rawq, Fq_N64);
364 | }
365 | }
366 |
--------------------------------------------------------------------------------
/build/fr.cpp:
--------------------------------------------------------------------------------
1 | #include "fr.hpp"
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 |
9 | static mpz_t q;
10 | static mpz_t zero;
11 | static mpz_t one;
12 | static mpz_t mask;
13 | static size_t nBits;
14 | static bool initialized = false;
15 |
16 | void Fr_toMpz(mpz_t r, PFrElement pE) {
17 | FrElement tmp;
18 | Fr_toNormal(&tmp, pE);
19 | if (!(tmp.type & Fr_LONG)) {
20 | mpz_set_si(r, tmp.shortVal);
21 | if (tmp.shortVal<0) {
22 | mpz_add(r, r, q);
23 | }
24 | } else {
25 | mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.longVal);
26 | }
27 | }
28 |
29 | void Fr_fromMpz(PFrElement pE, mpz_t v) {
30 | if (mpz_fits_sint_p(v)) {
31 | pE->type = Fr_SHORT;
32 | pE->shortVal = mpz_get_si(v);
33 | } else {
34 | pE->type = Fr_LONG;
35 | for (int i=0; ilongVal[i] = 0;
36 | mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
37 | }
38 | }
39 |
40 |
41 | bool Fr_init() {
42 | if (initialized) return false;
43 | initialized = true;
44 | mpz_init(q);
45 | mpz_import(q, Fr_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
46 | mpz_init_set_ui(zero, 0);
47 | mpz_init_set_ui(one, 1);
48 | nBits = mpz_sizeinbase (q, 2);
49 | mpz_init(mask);
50 | mpz_mul_2exp(mask, one, nBits);
51 | mpz_sub(mask, mask, one);
52 | return true;
53 | }
54 |
55 | void Fr_str2element(PFrElement pE, char const *s, uint base) {
56 | mpz_t mr;
57 | mpz_init_set_str(mr, s, base);
58 | mpz_fdiv_r(mr, mr, q);
59 | Fr_fromMpz(pE, mr);
60 | mpz_clear(mr);
61 | }
62 |
63 | char *Fr_element2str(PFrElement pE) {
64 | FrElement tmp;
65 | mpz_t r;
66 | if (!(pE->type & Fr_LONG)) {
67 | if (pE->shortVal>=0) {
68 | char *r = new char[32];
69 | sprintf(r, "%d", pE->shortVal);
70 | return r;
71 | } else {
72 | mpz_init_set_si(r, pE->shortVal);
73 | mpz_add(r, r, q);
74 | }
75 | } else {
76 | Fr_toNormal(&tmp, pE);
77 | mpz_init(r);
78 | mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.longVal);
79 | }
80 | char *res = mpz_get_str (0, 10, r);
81 | mpz_clear(r);
82 | return res;
83 | }
84 |
85 | void Fr_idiv(PFrElement r, PFrElement a, PFrElement b) {
86 | mpz_t ma;
87 | mpz_t mb;
88 | mpz_t mr;
89 | mpz_init(ma);
90 | mpz_init(mb);
91 | mpz_init(mr);
92 |
93 | Fr_toMpz(ma, a);
94 | // char *s1 = mpz_get_str (0, 10, ma);
95 | // printf("s1 %s\n", s1);
96 | Fr_toMpz(mb, b);
97 | // char *s2 = mpz_get_str (0, 10, mb);
98 | // printf("s2 %s\n", s2);
99 | mpz_fdiv_q(mr, ma, mb);
100 | // char *sr = mpz_get_str (0, 10, mr);
101 | // printf("r %s\n", sr);
102 | Fr_fromMpz(r, mr);
103 |
104 | mpz_clear(ma);
105 | mpz_clear(mb);
106 | mpz_clear(mr);
107 | }
108 |
109 | void Fr_mod(PFrElement r, PFrElement a, PFrElement b) {
110 | mpz_t ma;
111 | mpz_t mb;
112 | mpz_t mr;
113 | mpz_init(ma);
114 | mpz_init(mb);
115 | mpz_init(mr);
116 |
117 | Fr_toMpz(ma, a);
118 | Fr_toMpz(mb, b);
119 | mpz_fdiv_r(mr, ma, mb);
120 | Fr_fromMpz(r, mr);
121 |
122 | mpz_clear(ma);
123 | mpz_clear(mb);
124 | mpz_clear(mr);
125 | }
126 |
127 | void Fr_pow(PFrElement r, PFrElement a, PFrElement b) {
128 | mpz_t ma;
129 | mpz_t mb;
130 | mpz_t mr;
131 | mpz_init(ma);
132 | mpz_init(mb);
133 | mpz_init(mr);
134 |
135 | Fr_toMpz(ma, a);
136 | Fr_toMpz(mb, b);
137 | mpz_powm(mr, ma, mb, q);
138 | Fr_fromMpz(r, mr);
139 |
140 | mpz_clear(ma);
141 | mpz_clear(mb);
142 | mpz_clear(mr);
143 | }
144 |
145 | void Fr_inv(PFrElement r, PFrElement a) {
146 | mpz_t ma;
147 | mpz_t mr;
148 | mpz_init(ma);
149 | mpz_init(mr);
150 |
151 | Fr_toMpz(ma, a);
152 | mpz_invert(mr, ma, q);
153 | Fr_fromMpz(r, mr);
154 | mpz_clear(ma);
155 | mpz_clear(mr);
156 | }
157 |
158 | void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
159 | FrElement tmp;
160 | Fr_inv(&tmp, b);
161 | Fr_mul(r, a, &tmp);
162 | }
163 |
164 | void Fr_fail() {
165 | throw std::runtime_error("Fr error");
166 | }
167 |
168 | void Fr_longErr()
169 | {
170 | Fr_fail();
171 | }
172 |
173 | RawFr::RawFr() {
174 | Fr_init();
175 | set(fZero, 0);
176 | set(fOne, 1);
177 | neg(fNegOne, fOne);
178 | }
179 |
180 | RawFr::~RawFr() {
181 | }
182 |
183 | void RawFr::fromString(Element &r, const std::string &s, uint32_t radix) {
184 | mpz_t mr;
185 | mpz_init_set_str(mr, s.c_str(), radix);
186 | mpz_fdiv_r(mr, mr, q);
187 | for (int i=0; i>3] & (1 << (p & 0x7)))
259 | void RawFr::exp(Element &r, const Element &base, uint8_t* scalar, unsigned int scalarSize) {
260 | bool oneFound = false;
261 | Element copyBase;
262 | copy(copyBase, base);
263 | for (int i=scalarSize*8-1; i>=0; i--) {
264 | if (!oneFound) {
265 | if ( !BIT_IS_SET(scalar, i) ) continue;
266 | copy(r, copyBase);
267 | oneFound = true;
268 | continue;
269 | }
270 | square(r, r);
271 | if ( BIT_IS_SET(scalar, i) ) {
272 | mul(r, r, copyBase);
273 | }
274 | }
275 | if (!oneFound) {
276 | copy(r, fOne);
277 | }
278 | }
279 |
280 | void RawFr::toMpz(mpz_t r, const Element &a) {
281 | Element tmp;
282 | Fr_rawFromMontgomery(tmp.v, a.v);
283 | mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.v);
284 | }
285 |
286 | void RawFr::fromMpz(Element &r, const mpz_t a) {
287 | for (int i=0; i
6 | #include
7 | #include
8 |
9 | #ifdef __APPLE__
10 | #include // typedef unsigned int uint;
11 | #endif // __APPLE__
12 |
13 | extern FrElement Fr_q;
14 | extern FrElement Fr_R2;
15 | extern FrElement Fr_R3;
16 | extern FrRawElement Fr_rawq;
17 | extern FrRawElement Fr_rawR3;
18 |
19 | #ifdef USE_ASM
20 |
21 | #if defined(ARCH_X86_64)
22 |
23 | extern "C" void Fr_copy(PFrElement r, PFrElement a);
24 | extern "C" void Fr_copyn(PFrElement r, PFrElement a, int n);
25 | extern "C" void Fr_add(PFrElement r, PFrElement a, PFrElement b);
26 | extern "C" void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
27 | extern "C" void Fr_neg(PFrElement r, PFrElement a);
28 | extern "C" void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
29 | extern "C" void Fr_square(PFrElement r, PFrElement a);
30 | extern "C" void Fr_band(PFrElement r, PFrElement a, PFrElement b);
31 | extern "C" void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
32 | extern "C" void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
33 | extern "C" void Fr_bnot(PFrElement r, PFrElement a);
34 | extern "C" void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
35 | extern "C" void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
36 | extern "C" void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
37 | extern "C" void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
38 | extern "C" void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
39 | extern "C" void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
40 | extern "C" void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
41 | extern "C" void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
42 | extern "C" void Fr_land(PFrElement r, PFrElement a, PFrElement b);
43 | extern "C" void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
44 | extern "C" void Fr_lnot(PFrElement r, PFrElement a);
45 | extern "C" void Fr_toNormal(PFrElement r, PFrElement a);
46 | extern "C" void Fr_toLongNormal(PFrElement r, PFrElement a);
47 | extern "C" void Fr_toMontgomery(PFrElement r, PFrElement a);
48 |
49 | extern "C" int Fr_isTrue(PFrElement pE);
50 | extern "C" int Fr_toInt(PFrElement pE);
51 |
52 | extern "C" void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA);
53 | extern "C" void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA);
54 | extern "C" void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
55 | extern "C" void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
56 | extern "C" void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA);
57 | extern "C" void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
58 | extern "C" void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA);
59 | extern "C" void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB);
60 | extern "C" void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
61 | extern "C" void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
62 | extern "C" int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB);
63 | extern "C" int Fr_rawIsZero(const FrRawElement pRawB);
64 | extern "C" void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b);
65 | extern "C" void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b);
66 |
67 | extern "C" void Fr_fail();
68 |
69 | #elif defined(ARCH_ARM64)
70 |
71 | void Fr_copy(PFrElement r, PFrElement a);
72 | void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
73 | void Fr_toNormal(PFrElement r, PFrElement a);
74 |
75 | void Fr_toLongNormal(PFrElement r, PFrElement a);
76 | int Fr_isTrue(PFrElement pE);
77 | void Fr_copyn(PFrElement r, PFrElement a, int n);
78 | void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
79 | int Fr_toInt(PFrElement pE);
80 | void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
81 | void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
82 | void Fr_band(PFrElement r, PFrElement a, PFrElement b);
83 | void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
84 | void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
85 | void Fr_bnot(PFrElement r, PFrElement a);
86 | void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
87 | void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
88 | void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
89 | void Fr_add(PFrElement r, PFrElement a, PFrElement b);
90 | void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
91 | void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
92 | void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
93 | void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
94 | void Fr_lnot(PFrElement r, PFrElement a);
95 | void Fr_land(PFrElement r, PFrElement a, PFrElement b);
96 | void Fr_neg(PFrElement r, PFrElement a);
97 | void Fr_toMontgomery(PFrElement r, PFrElement a);
98 | void Fr_square(PFrElement r, PFrElement a);
99 |
100 | extern "C" void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA);
101 | extern "C" void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA);
102 | extern "C" void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
103 | extern "C" void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
104 | extern "C" void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA);
105 | extern "C" void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
106 | void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA);
107 | extern "C" void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB);
108 | void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
109 | extern "C" void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
110 | extern "C" int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB);
111 | extern "C" int Fr_rawIsZero(const FrRawElement pRawB);
112 | void Fr_rawZero(FrRawElement pRawResult);
113 | extern "C" void Fr_rawCopyS2L(FrRawElement pRawResult, int64_t val);
114 | extern "C" void Fr_rawAddLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
115 | extern "C" void Fr_rawSubSL(FrRawElement pRawResult, uint64_t rawA, FrRawElement pRawB);
116 | extern "C" void Fr_rawSubLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
117 | extern "C" void Fr_rawNegLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
118 | extern "C" int Fr_rawCmp(FrRawElement pRawA, FrRawElement pRawB);
119 | extern "C" void Fr_rawAnd(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
120 | extern "C" void Fr_rawOr(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
121 | extern "C" void Fr_rawXor(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
122 | extern "C" void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b);
123 | extern "C" void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b);
124 | extern "C" void Fr_rawNot(FrRawElement pRawResult, FrRawElement pRawA);
125 | extern "C" void Fr_rawSubRegular(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
126 |
127 | void Fr_fail();
128 | void Fr_longErr();
129 |
130 | #endif
131 |
132 | #else
133 |
134 |
135 | void Fr_copy(PFrElement r, PFrElement a);
136 | void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
137 | void Fr_toNormal(PFrElement r, PFrElement a);
138 |
139 | void Fr_toLongNormal(PFrElement r, PFrElement a);
140 | int Fr_isTrue(PFrElement pE);
141 | void Fr_copyn(PFrElement r, PFrElement a, int n);
142 | void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
143 | int Fr_toInt(PFrElement pE);
144 | void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
145 | void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
146 | void Fr_band(PFrElement r, PFrElement a, PFrElement b);
147 | void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
148 | void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
149 | void Fr_bnot(PFrElement r, PFrElement a);
150 | void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
151 | void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
152 | void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
153 | void Fr_add(PFrElement r, PFrElement a, PFrElement b);
154 | void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
155 | void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
156 | void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
157 | void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
158 | void Fr_lnot(PFrElement r, PFrElement a);
159 | void Fr_land(PFrElement r, PFrElement a, PFrElement b);
160 | void Fr_neg(PFrElement r, PFrElement a);
161 | void Fr_toMontgomery(PFrElement r, PFrElement a);
162 | void Fr_square(PFrElement r, PFrElement a);
163 |
164 | void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA);
165 | void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA);
166 | void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
167 | void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
168 | void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA);
169 | void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB);
170 | void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA);
171 | void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB);
172 | void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
173 | void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA);
174 | int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB);
175 | int Fr_rawIsZero(const FrRawElement pRawB);
176 | void Fr_rawZero(FrRawElement pRawResult);
177 | void Fr_rawCopyS2L(FrRawElement pRawResult, int64_t val);
178 | void Fr_rawAddLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
179 | void Fr_rawSubSL(FrRawElement pRawResult, uint64_t rawA, FrRawElement pRawB);
180 | void Fr_rawSubLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
181 | void Fr_rawNegLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB);
182 | int Fr_rawCmp(FrRawElement pRawA, FrRawElement pRawB);
183 | void Fr_rawAnd(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
184 | void Fr_rawOr(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
185 | void Fr_rawXor(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
186 | void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b);
187 | void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b);
188 | void Fr_rawNot(FrRawElement pRawResult, FrRawElement pRawA);
189 | void Fr_rawSubRegular(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB);
190 |
191 | void Fr_fail();
192 | void Fr_longErr();
193 |
194 | #endif
195 |
196 | // Pending functions to convert
197 |
198 | void Fr_str2element(PFrElement pE, char const*s, uint base);
199 | char *Fr_element2str(PFrElement pE);
200 | void Fr_idiv(PFrElement r, PFrElement a, PFrElement b);
201 | void Fr_mod(PFrElement r, PFrElement a, PFrElement b);
202 | void Fr_inv(PFrElement r, PFrElement a);
203 | void Fr_div(PFrElement r, PFrElement a, PFrElement b);
204 | void Fr_pow(PFrElement r, PFrElement a, PFrElement b);
205 |
206 | class RawFr {
207 |
208 | public:
209 | const static int N64 = Fr_N64;
210 | const static int MaxBits = 254;
211 |
212 |
213 | struct Element {
214 | FrRawElement v;
215 | };
216 |
217 | private:
218 | Element fZero;
219 | Element fOne;
220 | Element fNegOne;
221 |
222 | public:
223 |
224 | RawFr();
225 | ~RawFr();
226 |
227 | const Element &zero() { return fZero; };
228 | const Element &one() { return fOne; };
229 | const Element &negOne() { return fNegOne; };
230 | Element set(int value);
231 | void set(Element &r, int value);
232 |
233 | void fromString(Element &r, const std::string &n, uint32_t radix = 10);
234 | std::string toString(const Element &a, uint32_t radix = 10);
235 |
236 | void inline copy(Element &r, const Element &a) { Fr_rawCopy(r.v, a.v); };
237 | void inline swap(Element &a, Element &b) { Fr_rawSwap(a.v, b.v); };
238 | void inline add(Element &r, const Element &a, const Element &b) { Fr_rawAdd(r.v, a.v, b.v); };
239 | void inline sub(Element &r, const Element &a, const Element &b) { Fr_rawSub(r.v, a.v, b.v); };
240 | void inline mul(Element &r, const Element &a, const Element &b) { Fr_rawMMul(r.v, a.v, b.v); };
241 |
242 | Element inline add(const Element &a, const Element &b) { Element r; Fr_rawAdd(r.v, a.v, b.v); return r;};
243 | Element inline sub(const Element &a, const Element &b) { Element r; Fr_rawSub(r.v, a.v, b.v); return r;};
244 | Element inline mul(const Element &a, const Element &b) { Element r; Fr_rawMMul(r.v, a.v, b.v); return r;};
245 |
246 | Element inline neg(const Element &a) { Element r; Fr_rawNeg(r.v, a.v); return r; };
247 | Element inline square(const Element &a) { Element r; Fr_rawMSquare(r.v, a.v); return r; };
248 |
249 | Element inline add(int a, const Element &b) { return add(set(a), b);};
250 | Element inline sub(int a, const Element &b) { return sub(set(a), b);};
251 | Element inline mul(int a, const Element &b) { return mul(set(a), b);};
252 |
253 | Element inline add(const Element &a, int b) { return add(a, set(b));};
254 | Element inline sub(const Element &a, int b) { return sub(a, set(b));};
255 | Element inline mul(const Element &a, int b) { return mul(a, set(b));};
256 |
257 | void inline mul1(Element &r, const Element &a, uint64_t b) { Fr_rawMMul1(r.v, a.v, b); };
258 | void inline neg(Element &r, const Element &a) { Fr_rawNeg(r.v, a.v); };
259 | void inline square(Element &r, const Element &a) { Fr_rawMSquare(r.v, a.v); };
260 | void inv(Element &r, const Element &a);
261 | void div(Element &r, const Element &a, const Element &b);
262 | void exp(Element &r, const Element &base, uint8_t* scalar, unsigned int scalarSize);
263 |
264 | void inline toMontgomery(Element &r, const Element &a) { Fr_rawToMontgomery(r.v, a.v); };
265 | void inline fromMontgomery(Element &r, const Element &a) { Fr_rawFromMontgomery(r.v, a.v); };
266 | int inline eq(const Element &a, const Element &b) { return Fr_rawIsEq(a.v, b.v); };
267 | int inline isZero(const Element &a) { return Fr_rawIsZero(a.v); };
268 |
269 | void toMpz(mpz_t r, const Element &a);
270 | void fromMpz(Element &a, const mpz_t r);
271 |
272 | int toRprBE(const Element &element, uint8_t *data, int bytes);
273 | int fromRprBE(Element &element, const uint8_t *data, int bytes);
274 |
275 | int bytes ( void ) { return Fr_N64 * 8; };
276 |
277 | void fromUI(Element &r, unsigned long int v);
278 |
279 | static RawFr field;
280 |
281 | };
282 |
283 |
284 | #endif // __FR_H
285 |
286 |
287 |
288 |
--------------------------------------------------------------------------------
/build/fr_element.hpp:
--------------------------------------------------------------------------------
1 | #ifndef FR_ELEMENT_HPP
2 | #define FR_ELEMENT_HPP
3 |
4 | #include
5 |
6 | #define Fr_N64 4
7 | #define Fr_SHORT 0x00000000
8 | #define Fr_MONTGOMERY 0x40000000
9 | #define Fr_SHORTMONTGOMERY 0x40000000
10 | #define Fr_LONG 0x80000000
11 | #define Fr_LONGMONTGOMERY 0xC0000000
12 |
13 | typedef uint64_t FrRawElement[Fr_N64];
14 |
15 | typedef struct __attribute__((__packed__)) {
16 | int32_t shortVal;
17 | uint32_t type;
18 | FrRawElement longVal;
19 | } FrElement;
20 |
21 | typedef FrElement *PFrElement;
22 |
23 | #endif // FR_ELEMENT_HPP
24 |
--------------------------------------------------------------------------------
/build/fr_raw_generic.cpp:
--------------------------------------------------------------------------------
1 | #include "fr_element.hpp"
2 | #include
3 | #include
4 |
5 | static uint64_t Fr_rawq[] = {0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029, 0};
6 | static FrRawElement Fr_rawR2 = {0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5};
7 | static uint64_t Fr_np = {0xc2e1f593efffffff};
8 | static uint64_t lboMask = 0x3fffffffffffffff;
9 |
10 |
11 | void Fr_rawAdd(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
12 | {
13 | uint64_t carry = mpn_add_n(pRawResult, pRawA, pRawB, Fr_N64);
14 |
15 | if(carry || mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
16 | {
17 | mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
18 | }
19 | }
20 |
21 | void Fr_rawAddLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB)
22 | {
23 | uint64_t carry = mpn_add_1(pRawResult, pRawA, Fr_N64, rawB);
24 |
25 | if(carry || mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
26 | {
27 | mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
28 | }
29 | }
30 |
31 | void Fr_rawSub(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
32 | {
33 | uint64_t carry = mpn_sub_n(pRawResult, pRawA, pRawB, Fr_N64);
34 |
35 | if(carry)
36 | {
37 | mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
38 | }
39 | }
40 |
41 | void Fr_rawSubRegular(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
42 | {
43 | mpn_sub_n(pRawResult, pRawA, pRawB, Fr_N64);
44 | }
45 |
46 | void Fr_rawSubSL(FrRawElement pRawResult, uint64_t rawA, FrRawElement pRawB)
47 | {
48 | FrRawElement pRawA = {rawA, 0, 0, 0};
49 |
50 | uint64_t carry = mpn_sub_n(pRawResult, pRawA, pRawB, Fr_N64);
51 |
52 | if(carry)
53 | {
54 | mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
55 | }
56 | }
57 |
58 | void Fr_rawSubLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB)
59 | {
60 | uint64_t carry = mpn_sub_1(pRawResult, pRawA, Fr_N64, rawB);
61 |
62 | if(carry)
63 | {
64 | mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
65 | }
66 | }
67 |
68 | void Fr_rawNeg(FrRawElement pRawResult, const FrRawElement pRawA)
69 | {
70 | const uint64_t zero[Fr_N64] = {0, 0, 0, 0};
71 |
72 | if (mpn_cmp(pRawA, zero, Fr_N64) != 0)
73 | {
74 | mpn_sub_n(pRawResult, Fr_rawq, pRawA, Fr_N64);
75 | }
76 | else
77 | {
78 | mpn_copyi(pRawResult, zero, Fr_N64);
79 | }
80 | }
81 |
82 | // Substracts a long element and a short element form 0
83 | void Fr_rawNegLS(FrRawElement pRawResult, FrRawElement pRawA, uint64_t rawB)
84 | {
85 | uint64_t carry1 = mpn_sub_1(pRawResult, Fr_rawq, Fr_N64, rawB);
86 | uint64_t carry2 = mpn_sub_n(pRawResult, pRawResult, pRawA, Fr_N64);
87 |
88 | if (carry1 || carry2)
89 | {
90 | mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
91 | }
92 | }
93 |
94 | void Fr_rawCopy(FrRawElement pRawResult, const FrRawElement pRawA)
95 | {
96 | pRawResult[0] = pRawA[0];
97 | pRawResult[1] = pRawA[1];
98 | pRawResult[2] = pRawA[2];
99 | pRawResult[3] = pRawA[3];
100 | }
101 |
102 | int Fr_rawIsEq(const FrRawElement pRawA, const FrRawElement pRawB)
103 | {
104 | return mpn_cmp(pRawA, pRawB, Fr_N64) == 0;
105 | }
106 |
107 | void Fr_rawMMul(FrRawElement pRawResult, const FrRawElement pRawA, const FrRawElement pRawB)
108 | {
109 | const mp_size_t N = Fr_N64+1;
110 | const uint64_t *mq = Fr_rawq;
111 |
112 | uint64_t np0;
113 |
114 | uint64_t product0[N] = {0};
115 | uint64_t product1[N] = {0};
116 | uint64_t product2[N] = {0};
117 | uint64_t product3[N] = {0};
118 |
119 | product0[4] = mpn_mul_1(product0, pRawB, Fr_N64, pRawA[0]);
120 |
121 | np0 = Fr_np * product0[0];
122 | product1[1] = mpn_addmul_1(product0, mq, N, np0);
123 |
124 | product1[4] = mpn_addmul_1(product1, pRawB, Fr_N64, pRawA[1]);
125 | mpn_add(product1, product1, N, product0+1, N-1);
126 |
127 | np0 = Fr_np * product1[0];
128 | product2[1] = mpn_addmul_1(product1, mq, N, np0);
129 |
130 | product2[4] = mpn_addmul_1(product2, pRawB, Fr_N64, pRawA[2]);
131 | mpn_add(product2, product2, N, product1+1, N-1);
132 |
133 | np0 = Fr_np * product2[0];
134 | product3[1] = mpn_addmul_1(product2, mq, N, np0);
135 |
136 | product3[4] = mpn_addmul_1(product3, pRawB, Fr_N64, pRawA[3]);
137 | mpn_add(product3, product3, N, product2+1, N-1);
138 |
139 | np0 = Fr_np * product3[0];
140 | mpn_addmul_1(product3, mq, N, np0);
141 |
142 | mpn_copyi(pRawResult, product3+1, Fr_N64);
143 |
144 | if (mpn_cmp(pRawResult, mq, Fr_N64) >= 0)
145 | {
146 | mpn_sub_n(pRawResult, pRawResult, mq, Fr_N64);
147 | }
148 | }
149 |
150 | void Fr_rawMSquare(FrRawElement pRawResult, const FrRawElement pRawA)
151 | {
152 | Fr_rawMMul(pRawResult, pRawA, pRawA);
153 | }
154 |
155 | void Fr_rawMMul1(FrRawElement pRawResult, const FrRawElement pRawA, uint64_t pRawB)
156 | {
157 | const mp_size_t N = Fr_N64+1;
158 | const uint64_t *mq = Fr_rawq;
159 |
160 | uint64_t np0;
161 |
162 | uint64_t product0[N] = {0};
163 | uint64_t product1[N] = {0};
164 | uint64_t product2[N] = {0};
165 | uint64_t product3[N] = {0};
166 |
167 | product0[4] = mpn_mul_1(product0, pRawA, Fr_N64, pRawB);
168 |
169 | np0 = Fr_np * product0[0];
170 | product1[1] = mpn_addmul_1(product0, mq, N, np0);
171 | mpn_add(product1, product1, N, product0+1, N-1);
172 |
173 | np0 = Fr_np * product1[0];
174 | product2[1] = mpn_addmul_1(product1, mq, N, np0);
175 | mpn_add(product2, product2, N, product1+1, N-1);
176 |
177 | np0 = Fr_np * product2[0];
178 | product3[1] = mpn_addmul_1(product2, mq, N, np0);
179 | mpn_add(product3, product3, N, product2+1, N-1);
180 |
181 | np0 = Fr_np * product3[0];
182 | mpn_addmul_1(product3, mq, N, np0);
183 |
184 | mpn_copyi(pRawResult, product3+1, Fr_N64);
185 |
186 | if (mpn_cmp(pRawResult, mq, Fr_N64) >= 0)
187 | {
188 | mpn_sub_n(pRawResult, pRawResult, mq, Fr_N64);
189 | }
190 | }
191 |
192 | void Fr_rawToMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA)
193 | {
194 | Fr_rawMMul(pRawResult, pRawA, Fr_rawR2);
195 | }
196 |
197 | void Fr_rawFromMontgomery(FrRawElement pRawResult, const FrRawElement &pRawA)
198 | {
199 | const mp_size_t N = Fr_N64+1;
200 | const uint64_t *mq = Fr_rawq;
201 |
202 | uint64_t np0;
203 |
204 | uint64_t product0[N];
205 | uint64_t product1[N] = {0};
206 | uint64_t product2[N] = {0};
207 | uint64_t product3[N] = {0};
208 |
209 | mpn_copyi(product0, pRawA, Fr_N64); product0[4] = 0;
210 |
211 | np0 = Fr_np * product0[0];
212 | product1[1] = mpn_addmul_1(product0, mq, N, np0);
213 | mpn_add(product1, product1, N, product0+1, N-1);
214 |
215 | np0 = Fr_np * product1[0];
216 | product2[1] = mpn_addmul_1(product1, mq, N, np0);
217 | mpn_add(product2, product2, N, product1+1, N-1);
218 |
219 | np0 = Fr_np * product2[0];
220 | product3[1] = mpn_addmul_1(product2, mq, N, np0);
221 | mpn_add(product3, product3, N, product2+1, N-1);
222 |
223 | np0 = Fr_np * product3[0];
224 | mpn_addmul_1(product3, mq, N, np0);
225 |
226 | mpn_copyi(pRawResult, product3+1, Fr_N64);
227 |
228 | if (mpn_cmp(pRawResult, mq, Fr_N64) >= 0)
229 | {
230 | mpn_sub_n(pRawResult, pRawResult, mq, Fr_N64);
231 | }
232 | }
233 |
234 | int Fr_rawIsZero(const FrRawElement rawA)
235 | {
236 | return mpn_zero_p(rawA, Fr_N64) ? 1 : 0;
237 | }
238 |
239 | int Fr_rawCmp(FrRawElement pRawA, FrRawElement pRawB)
240 | {
241 | return mpn_cmp(pRawA, pRawB, Fr_N64);
242 | }
243 |
244 | void Fr_rawSwap(FrRawElement pRawResult, FrRawElement pRawA)
245 | {
246 | FrRawElement temp;
247 |
248 | temp[0] = pRawResult[0];
249 | temp[1] = pRawResult[1];
250 | temp[2] = pRawResult[2];
251 | temp[3] = pRawResult[3];
252 |
253 | pRawResult[0] = pRawA[0];
254 | pRawResult[1] = pRawA[1];
255 | pRawResult[2] = pRawA[2];
256 | pRawResult[3] = pRawA[3];
257 |
258 | pRawA[0] = temp[0];
259 | pRawA[1] = temp[1];
260 | pRawA[2] = temp[2];
261 | pRawA[3] = temp[3];
262 | }
263 |
264 | void Fr_rawCopyS2L(FrRawElement pRawResult, int64_t val)
265 | {
266 | pRawResult[0] = val;
267 | pRawResult[1] = 0;
268 | pRawResult[2] = 0;
269 | pRawResult[3] = 0;
270 |
271 | if (val < 0)
272 | {
273 | pRawResult[1] = -1;
274 | pRawResult[2] = -1;
275 | pRawResult[3] = -1;
276 |
277 | mpn_add_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
278 | }
279 | }
280 |
281 | void Fr_rawAnd(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
282 | {
283 | mpn_and_n(pRawResult, pRawA, pRawB, Fr_N64);
284 |
285 | pRawResult[3] &= lboMask;
286 |
287 | if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
288 | {
289 | mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
290 | }
291 | }
292 |
293 | void Fr_rawOr(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
294 | {
295 | mpn_ior_n(pRawResult, pRawA, pRawB, Fr_N64);
296 |
297 | pRawResult[3] &= lboMask;
298 |
299 | if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
300 | {
301 | mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
302 | }
303 | }
304 |
305 | void Fr_rawXor(FrRawElement pRawResult, FrRawElement pRawA, FrRawElement pRawB)
306 | {
307 | mpn_xor_n(pRawResult, pRawA, pRawB, Fr_N64);
308 |
309 | pRawResult[3] &= lboMask;
310 |
311 | if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
312 | {
313 | mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
314 | }
315 | }
316 |
317 | void Fr_rawShl(FrRawElement r, FrRawElement a, uint64_t b)
318 | {
319 | uint64_t bit_shift = b % 64;
320 | uint64_t word_shift = b / 64;
321 | uint64_t word_count = Fr_N64 - word_shift;
322 |
323 | mpn_copyi(r + word_shift, a, word_count);
324 | std::memset(r, 0, word_shift * sizeof(uint64_t));
325 |
326 | if (bit_shift)
327 | {
328 | mpn_lshift(r, r, Fr_N64, bit_shift);
329 | }
330 |
331 | r[3] &= lboMask;
332 |
333 | if (mpn_cmp(r, Fr_rawq, Fr_N64) >= 0)
334 | {
335 | mpn_sub_n(r, r, Fr_rawq, Fr_N64);
336 | }
337 | }
338 |
339 | void Fr_rawShr(FrRawElement r, FrRawElement a, uint64_t b)
340 | {
341 | const uint64_t bit_shift = b % 64;
342 | const uint64_t word_shift = b / 64;
343 | const uint64_t word_count = Fr_N64 - word_shift;
344 |
345 | mpn_copyi(r, a + word_shift, word_count);
346 | std::memset(r + word_count, 0, word_shift * sizeof(uint64_t));
347 |
348 | if (bit_shift)
349 | {
350 | mpn_rshift(r, r, Fr_N64, bit_shift);
351 | }
352 | }
353 |
354 | void Fr_rawNot(FrRawElement pRawResult, FrRawElement pRawA)
355 | {
356 | mpn_com(pRawResult, pRawA, Fr_N64);
357 |
358 | pRawResult[3] &= lboMask;
359 |
360 | if (mpn_cmp(pRawResult, Fr_rawq, Fr_N64) >= 0)
361 | {
362 | mpn_sub_n(pRawResult, pRawResult, Fr_rawq, Fr_N64);
363 | }
364 | }
365 |
--------------------------------------------------------------------------------
/build_gmp.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | NPROC=8
6 | fetch_cmd=$( (type wget > /dev/null 2>&1 && echo "wget") || echo "curl -O" )
7 |
8 | usage()
9 | {
10 | echo "USAGE: $0 "
11 | echo "where target is one of:"
12 | echo " ios: build for iOS arm64"
13 | echo " ios_simulator: build for iPhone Simulator for arm64/x86_64 (fat binary)"
14 | echo " macos: build for macOS for arm64/x86_64 (fat binary)"
15 | echo " macos_arm64: build for macOS arm64"
16 | echo " macos_x86_64: build for macOS x86_64"
17 | echo " android: build for Android arm64"
18 | echo " android_x86_64: build for Android x86_64"
19 | echo " host: build for this host"
20 | echo " host_noasm: build for this host without asm optimizations (e.g. needed for macOS)"
21 | echo " aarch64: build for Linux aarch64"
22 |
23 | exit 1
24 | }
25 |
26 | get_gmp()
27 | {
28 | GMP_NAME=gmp-6.2.1
29 | GMP_ARCHIVE=${GMP_NAME}.tar.xz
30 | GMP_URL=https://ftp.gnu.org/gnu/gmp/${GMP_ARCHIVE}
31 |
32 | if [ ! -f ${GMP_ARCHIVE} ]; then
33 |
34 | $fetch_cmd ${GMP_URL}
35 | fi
36 |
37 |
38 | if [ ! -d gmp ]; then
39 |
40 | tar -xvf ${GMP_ARCHIVE}
41 | mv ${GMP_NAME} gmp
42 | fi
43 | }
44 |
45 | build_aarch64()
46 | {
47 | PACKAGE_DIR="$GMP_DIR/package_aarch64"
48 | BUILD_DIR=build_aarch64
49 |
50 | if [ -d "$PACKAGE_DIR" ]; then
51 | echo "aarch64 package is built already. See $PACKAGE_DIR"
52 | return 1
53 | fi
54 |
55 |
56 | export TARGET=aarch64-linux-gnu
57 |
58 | echo $TARGET
59 |
60 | rm -rf "$BUILD_DIR"
61 | mkdir "$BUILD_DIR"
62 | cd "$BUILD_DIR"
63 |
64 | ../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
65 | make -j${NPROC} &&
66 | make install
67 |
68 | cd ..
69 | }
70 |
71 | build_host()
72 | {
73 | PACKAGE_DIR="$GMP_DIR/package"
74 | BUILD_DIR=build
75 |
76 | if [ -d "$PACKAGE_DIR" ]; then
77 | echo "Host package is built already. See $PACKAGE_DIR"
78 | return 1
79 | fi
80 |
81 | rm -rf "$BUILD_DIR"
82 | mkdir "$BUILD_DIR"
83 | cd "$BUILD_DIR"
84 |
85 | ../configure --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
86 | make -j${NPROC} &&
87 | make install
88 |
89 | cd ..
90 | }
91 |
92 | build_host_noasm()
93 | {
94 | PACKAGE_DIR="$GMP_DIR/package"
95 | BUILD_DIR=build
96 |
97 | if [ -d "$PACKAGE_DIR" ]; then
98 | echo "Host package is built already. See $PACKAGE_DIR"
99 | return 1
100 | fi
101 |
102 | rm -rf "$BUILD_DIR"
103 | mkdir "$BUILD_DIR"
104 | cd "$BUILD_DIR"
105 |
106 | ../configure --prefix="$PACKAGE_DIR" --with-pic --disable-fft --disable-assembly &&
107 | make -j${NPROC} &&
108 | make install
109 |
110 | cd ..
111 | }
112 |
113 | build_android()
114 | {
115 | PACKAGE_DIR="$GMP_DIR/package_android_arm64"
116 | BUILD_DIR=build_android_arm64
117 |
118 | if [ -d "$PACKAGE_DIR" ]; then
119 | echo "Android package is built already. See $PACKAGE_DIR"
120 | return 1
121 | fi
122 |
123 | if [ -z "$ANDROID_NDK" ]; then
124 |
125 | echo "ERROR: ANDROID_NDK environment variable is not set."
126 | echo " It must be an absolute path to the root directory of Android NDK."
127 | echo " For instance /home/test/Android/Sdk/ndk/23.1.7779620"
128 | return 1
129 | fi
130 |
131 | if [ "$(uname)" == "Darwin" ]; then
132 | export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
133 | else
134 | export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
135 | fi
136 |
137 | export TARGET=aarch64-linux-android
138 | export API=21
139 |
140 | export AR=$TOOLCHAIN/bin/llvm-ar
141 | export CC=$TOOLCHAIN/bin/$TARGET$API-clang
142 | export AS=$CC
143 | export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
144 | export LD=$TOOLCHAIN/bin/ld
145 | export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
146 | export STRIP=$TOOLCHAIN/bin/llvm-strip
147 |
148 | echo "$TOOLCHAIN"
149 | echo "$TARGET"
150 |
151 | rm -rf "$BUILD_DIR"
152 | mkdir "$BUILD_DIR"
153 | cd "$BUILD_DIR"
154 |
155 | ../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
156 | make -j${NPROC} &&
157 | make install
158 |
159 | cd ..
160 | }
161 |
162 | build_android_x86_64()
163 | {
164 | PACKAGE_DIR="$GMP_DIR/package_android_x86_64"
165 | BUILD_DIR=build_android_x86_64
166 |
167 | if [ -d "$PACKAGE_DIR" ]; then
168 | echo "Android package is built already. See $PACKAGE_DIR"
169 | return 1
170 | fi
171 |
172 | if [ -z "$ANDROID_NDK" ]; then
173 |
174 | echo "ERROR: ANDROID_NDK environment variable is not set."
175 | echo " It must be an absolute path to the root directory of Android NDK."
176 | echo " For instance /home/test/Android/Sdk/ndk/23.1.7779620"
177 | return 1
178 | fi
179 |
180 | if [ "$(uname)" == "Darwin" ]; then
181 | export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
182 | else
183 | export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
184 | fi
185 |
186 | export TARGET=x86_64-linux-android
187 | export API=21
188 |
189 | export AR=$TOOLCHAIN/bin/llvm-ar
190 | export CC=$TOOLCHAIN/bin/$TARGET$API-clang
191 | export AS=$CC
192 | export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
193 | export LD=$TOOLCHAIN/bin/ld
194 | export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
195 | export STRIP=$TOOLCHAIN/bin/llvm-strip
196 |
197 | echo "$TOOLCHAIN"
198 | echo $TARGET
199 |
200 | rm -rf "$BUILD_DIR"
201 | mkdir "$BUILD_DIR"
202 | cd "$BUILD_DIR"
203 |
204 | ../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
205 | make -j${NPROC} &&
206 | make install
207 |
208 | cd ..
209 | }
210 |
211 | build_ios()
212 | {
213 | PACKAGE_DIR="$GMP_DIR/package_ios_arm64"
214 | BUILD_DIR=build_ios_arm64
215 |
216 | if [ -d "$PACKAGE_DIR" ]; then
217 | echo "iOS package is built already. See $PACKAGE_DIR"
218 | return 1
219 | fi
220 |
221 | export SDK="iphoneos"
222 | export TARGET=arm64-apple-darwin
223 | export MIN_IOS_VERSION=8.0
224 |
225 | export ARCH_FLAGS="-arch arm64 -arch arm64e"
226 | export OPT_FLAGS="-O3 -g3 -fembed-bitcode"
227 | HOST_FLAGS="${ARCH_FLAGS} -miphoneos-version-min=${MIN_IOS_VERSION} -isysroot $(xcrun --sdk ${SDK} --show-sdk-path)"
228 |
229 | CC=$(xcrun --find --sdk "${SDK}" clang)
230 | export CC
231 | CXX=$(xcrun --find --sdk "${SDK}" clang++)
232 | export CXX
233 | CPP=$(xcrun --find --sdk "${SDK}" cpp)
234 | export CPP
235 | export CFLAGS="${HOST_FLAGS} ${OPT_FLAGS}"
236 | export CXXFLAGS="${HOST_FLAGS} ${OPT_FLAGS}"
237 | export LDFLAGS="${HOST_FLAGS}"
238 |
239 | echo $TARGET
240 |
241 | rm -rf "$BUILD_DIR"
242 | mkdir "$BUILD_DIR"
243 | cd "$BUILD_DIR"
244 |
245 | ../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft --disable-assembly &&
246 | make -j${NPROC} &&
247 | make install
248 |
249 | cd ..
250 | }
251 |
252 | build_ios_simulator()
253 | {
254 | libs=()
255 | for ARCH in "arm64" "x86_64"; do
256 | case "$ARCH" in
257 | "arm64" )
258 | echo "Building for iPhone Simulator arm64"
259 | ARCH_FLAGS="-arch arm64 -arch arm64e"
260 | ;;
261 | "x86_64" )
262 | echo "Building for iPhone Simulator x86_64"
263 | ARCH_FLAGS="-arch x86_64"
264 | ;;
265 | * )
266 | echo "Incorrect iPhone Simulator arch"
267 | exit 1
268 | esac
269 |
270 | BUILD_DIR="build_iphone_simulator_${ARCH}"
271 | PACKAGE_DIR="$GMP_DIR/package_iphone_simulator_${ARCH}"
272 | libs+=("${PACKAGE_DIR}/lib/libgmp.a")
273 |
274 | if [ -d "$PACKAGE_DIR" ]; then
275 | echo "iPhone Simulator ${ARCH} package is built already. See $PACKAGE_DIR. Skip building this ARCH."
276 | continue
277 | fi
278 |
279 | rm -rf "$BUILD_DIR"
280 | mkdir "$BUILD_DIR"
281 | cd "$BUILD_DIR"
282 |
283 | ../configure --prefix="${PACKAGE_DIR}" \
284 | CC="$(xcrun --sdk iphonesimulator --find clang)" \
285 | CFLAGS="-O3 -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path) ${ARCH_FLAGS} -fvisibility=hidden -mios-simulator-version-min=8.0" \
286 | LDFLAGS="" \
287 | --host ${ARCH}-apple-darwin --disable-assembly --enable-static --disable-shared --with-pic &&
288 | make -j${NPROC} &&
289 | make install
290 |
291 | cd ..
292 | done
293 |
294 | mkdir -p "${GMP_DIR}/package_iphone_simulator/lib"
295 | lipo "${libs[@]}" -create -output "${GMP_DIR}/package_iphone_simulator/lib/libgmp.a"
296 | echo "Wrote universal fat library for iPhone Simulator arm64/x86_64 to ${GMP_DIR}/package_iphone_simulator/lib/libgmp.a"
297 | }
298 |
299 | build_macos_arch()
300 | {
301 | ARCH="$1"
302 | case "$ARCH" in
303 | "arm64" )
304 | ARCH_FLAGS="-arch arm64 -arch arm64e"
305 | ;;
306 | "x86_64" )
307 | ARCH_FLAGS="-arch x86_64"
308 | ;;
309 | * )
310 | echo "Incorrect arch"
311 | exit 1
312 | esac
313 |
314 | BUILD_DIR="build_macos_${ARCH}"
315 | PACKAGE_DIR="$GMP_DIR/package_macos_${ARCH}"
316 | if [ -d "$PACKAGE_DIR" ]; then
317 | echo "macOS ${ARCH} package is built already. See $PACKAGE_DIR. Skip building this ARCH."
318 | return
319 | fi
320 | rm -rf "$BUILD_DIR"
321 | mkdir "$BUILD_DIR"
322 | cd "$BUILD_DIR"
323 | ../configure --prefix="${PACKAGE_DIR}" \
324 | CC="$(xcrun --sdk macosx --find clang)" \
325 | CFLAGS="-O3 -isysroot $(xcrun --sdk macosx --show-sdk-path) ${ARCH_FLAGS} -fvisibility=hidden -mmacos-version-min=14.0" \
326 | LDFLAGS="" \
327 | --host "${ARCH}-apple-darwin" --disable-assembly --enable-static --disable-shared --with-pic &&
328 | make -j${NPROC} &&
329 | make install
330 | cd ..
331 | }
332 |
333 | build_macos_fat()
334 | {
335 | echo "Building for macOS arm64"
336 | build_macos_arch "arm64"
337 | echo "Building for macOS x86_64"
338 | build_macos_arch "x86_64"
339 |
340 | gmp_lib_arm64="$GMP_DIR/package_macos_arm64/lib/libgmp.a"
341 | gmp_lib_x86_64="$GMP_DIR/package_macos_x86_64/lib/libgmp.a"
342 | gmp_lib_fat="$GMP_DIR/package_macos/lib/libgmp.a"
343 |
344 | mkdir -p "${GMP_DIR}/package_macos/lib"
345 | lipo "${gmp_lib_arm64}" "${gmp_lib_x86_64}" -create -output "${gmp_lib_fat}"
346 | mkdir -p "${GMP_DIR}/package_macos/include"
347 | cp "${GMP_DIR}/package_macos_arm64/include/gmp.h" "${GMP_DIR}/package_macos/include/"
348 | echo "Wrote universal fat library for macOS arm64/x86_64 to ${GMP_DIR}/package_macos/lib/libgmp.a"
349 | }
350 |
351 | if [ $# -ne 1 ]; then
352 | usage
353 | fi
354 |
355 | TARGET_PLATFORM=$(echo "$1" | tr "[:upper:]" "[:lower:]")
356 |
357 | cd depends
358 |
359 | get_gmp
360 |
361 | cd gmp
362 |
363 | GMP_DIR=$PWD
364 |
365 | case "$TARGET_PLATFORM" in
366 |
367 | "ios" )
368 | echo "Building for ios"
369 | build_ios
370 | ;;
371 |
372 | "ios_simulator" )
373 | echo "Building for iPhone Simulator"
374 | build_ios_simulator
375 | ;;
376 |
377 | "macos" )
378 | echo "Building fat library for macOS"
379 | build_macos_fat
380 | ;;
381 |
382 | "macos_arm64" )
383 | echo "Building library for macOS arm64"
384 | build_macos_arch "arm64"
385 | ;;
386 |
387 | "macos_x86_64" )
388 | echo "Building library for macOS x86_64"
389 | build_macos_arch "x86_64"
390 | ;;
391 |
392 | "android" )
393 | echo "Building for android"
394 | build_android
395 | ;;
396 |
397 | "android_x86_64" )
398 | echo "Building for android x86_64"
399 | build_android_x86_64
400 | ;;
401 |
402 | "host" )
403 | echo "Building for this host"
404 | build_host
405 | ;;
406 |
407 | "host_noasm" )
408 | echo "Building for this host without asm optimizations (e.g. needed for macOS)"
409 | build_host_noasm
410 | ;;
411 |
412 | "aarch64" )
413 | echo "Building for linux aarch64"
414 | build_aarch64
415 | ;;
416 |
417 | * )
418 | usage
419 |
420 | esac
421 |
--------------------------------------------------------------------------------
/cmake/platform.cmake:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.10)
2 |
3 | string(TOLOWER "${TARGET_PLATFORM}" TARGET_PLATFORM)
4 |
5 | message("Building for " ${TARGET_PLATFORM})
6 |
7 | set(GMP_ROOT depends/gmp)
8 |
9 | if(TARGET_PLATFORM MATCHES "android")
10 |
11 | if(NOT DEFINED ENV{ANDROID_NDK})
12 | message("ANDROID_NDK environment variable is not set.")
13 | message("It must be an absolute path to the root directory of Android NDK.")
14 | message(" For instance /home/test/Android/Sdk/ndk/23.1.7779620")
15 | message(FATAL_ERROR "Build failed.")
16 | else()
17 | message("Android NDK path is " $ENV{ANDROID_NDK})
18 | endif()
19 |
20 | set(CMAKE_SYSTEM_NAME Android)
21 | set(CMAKE_SYSTEM_VERSION 23) # API level
22 |
23 | if(TARGET_PLATFORM MATCHES "android_x86_64")
24 | set(CMAKE_ANDROID_ARCH_ABI x86_64)
25 | set(GMP_PREFIX ${GMP_ROOT}/package_android_x86_64)
26 | set(ARCH x86_64)
27 | else()
28 | set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
29 | set(GMP_PREFIX ${GMP_ROOT}/package_android_arm64)
30 | set(ARCH arm64)
31 | endif()
32 |
33 | message("CMAKE_ANDROID_ARCH_ABI=" ${CMAKE_ANDROID_ARCH_ABI})
34 |
35 | elseif(TARGET_PLATFORM MATCHES "ios")
36 |
37 | set(CMAKE_SYSTEM_NAME iOS)
38 |
39 | if(TARGET_PLATFORM MATCHES "ios_x86_64")
40 | set(CMAKE_OSX_ARCHITECTURES x86_64)
41 | set(GMP_PREFIX ${GMP_ROOT}/package_ios_x86_64)
42 | set(ARCH x86_64)
43 | elseif(TARGET_PLATFORM MATCHES "ios_simulator")
44 | set(CMAKE_OSX_ARCHITECTURES arm64)
45 | set(GMP_PREFIX ${GMP_ROOT}/package_iphone_simulator_arm64)
46 | set(ARCH x86_64)
47 | else()
48 | set(CMAKE_OSX_ARCHITECTURES arm64)
49 | set(GMP_PREFIX ${GMP_ROOT}/package_ios_arm64)
50 | set(ARCH arm64)
51 | endif()
52 |
53 | elseif(TARGET_PLATFORM MATCHES "aarch64")
54 |
55 | set(GMP_PREFIX ${GMP_ROOT}/package_aarch64)
56 | set(ARCH arm64)
57 |
58 | elseif(TARGET_PLATFORM MATCHES "macos_x86_64")
59 |
60 | set(CMAKE_OSX_ARCHITECTURES x86_64)
61 | set(GMP_PREFIX ${GMP_ROOT}/package_macos_x86_64)
62 | set(ARCH x86_64)
63 |
64 | elseif(TARGET_PLATFORM MATCHES "macos_arm64")
65 |
66 | set(CMAKE_OSX_ARCHITECTURES arm64)
67 | set(GMP_PREFIX ${GMP_ROOT}/package_macos_arm64)
68 | set(ARCH arm64)
69 |
70 | else()
71 |
72 | set(GMP_PREFIX ${GMP_ROOT}/package)
73 | set(ARCH x86_64)
74 |
75 | endif()
76 |
77 | if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" AND NOT TARGET_PLATFORM MATCHES "^android(_x86_64)?")
78 | set(GMP_DEFINIONS -D_LONG_LONG_LIMB)
79 | endif()
80 |
81 |
82 | set(GMP_INCLUDE_DIR ${GMP_PREFIX}/include)
83 | set(GMP_INCLUDE_FILE gmp.h)
84 | set(GMP_LIB_DIR ${GMP_PREFIX}/lib)
85 | set(GMP_LIB_FILE libgmp.a)
86 |
87 | set(GMP_LIB_FILE_FULLPATH ${CMAKE_SOURCE_DIR}/${GMP_LIB_DIR}/${GMP_LIB_FILE})
88 | set(GMP_INCLUDE_FILE_FULLPATH ${CMAKE_SOURCE_DIR}/${GMP_INCLUDE_DIR}/${GMP_INCLUDE_FILE})
89 |
90 | set(GMP_LIB ${GMP_LIB_FILE_FULLPATH})
91 |
92 | message("CMAKE_HOST_SYSTEM_NAME=" ${CMAKE_HOST_SYSTEM_NAME})
93 | message("CMAKE_SYSTEM_NAME=" ${CMAKE_SYSTEM_NAME})
94 | message("ARCH=" ${ARCH})
95 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rapidsnark",
3 | "version": "0.0.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@pawelgalazka/cli": {
8 | "version": "2.0.3",
9 | "resolved": "https://registry.npmjs.org/@pawelgalazka/cli/-/cli-2.0.3.tgz",
10 | "integrity": "sha512-PjR8WGDfd8KLFdRS0ceZC/V99xCMN+z6MVThoaqODEOrgwSyP1qA1nVc8JXOI5cxGQ5OBvSDikrvulXYnzgIjg==",
11 | "dev": true,
12 | "requires": {
13 | "@pawelgalazka/cli-args": "1.1.3",
14 | "@pawelgalazka/middleware": "1.0.0",
15 | "chalk": "2.4.2",
16 | "lodash": "4.17.15"
17 | },
18 | "dependencies": {
19 | "lodash": {
20 | "version": "4.17.15",
21 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
22 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
23 | "dev": true
24 | }
25 | }
26 | },
27 | "@pawelgalazka/cli-args": {
28 | "version": "1.1.3",
29 | "resolved": "https://registry.npmjs.org/@pawelgalazka/cli-args/-/cli-args-1.1.3.tgz",
30 | "integrity": "sha512-snkj9nX11F/2+7t/aQUbGC4iYMMZ2BQMoSsJ0IUUimzkOM9jb12QFAGubsOo9TibmfTN/g0DJ+ciOgXB/YEClQ==",
31 | "dev": true
32 | },
33 | "@pawelgalazka/middleware": {
34 | "version": "1.0.0",
35 | "resolved": "https://registry.npmjs.org/@pawelgalazka/middleware/-/middleware-1.0.0.tgz",
36 | "integrity": "sha512-BHE0ZFTDhfrAWzeoeUkhKXCjh0NFcd7dYJJiekW6sp3xbhaWTVBoaJbyZthWJEeow4FHJInjeEIBwbkGKqZzRg==",
37 | "dev": true
38 | },
39 | "@pawelgalazka/shell": {
40 | "version": "2.0.0",
41 | "resolved": "https://registry.npmjs.org/@pawelgalazka/shell/-/shell-2.0.0.tgz",
42 | "integrity": "sha512-MsNuS9M2vVbJNW3+YSiz9eF0/U2ZPlEEVC4ky8QJnxFlU4H7DZOH5A1hDQUfF5DV/pYwBD76dkF3+mrzZTJ3Tw==",
43 | "dev": true
44 | },
45 | "ansi-styles": {
46 | "version": "3.2.1",
47 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
48 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
49 | "dev": true,
50 | "requires": {
51 | "color-convert": "^1.9.0"
52 | }
53 | },
54 | "chalk": {
55 | "version": "2.4.2",
56 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
57 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
58 | "dev": true,
59 | "requires": {
60 | "ansi-styles": "^3.2.1",
61 | "escape-string-regexp": "^1.0.5",
62 | "supports-color": "^5.3.0"
63 | }
64 | },
65 | "color-convert": {
66 | "version": "1.9.3",
67 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
68 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
69 | "dev": true,
70 | "requires": {
71 | "color-name": "1.1.3"
72 | }
73 | },
74 | "color-name": {
75 | "version": "1.1.3",
76 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
77 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
78 | "dev": true
79 | },
80 | "escape-string-regexp": {
81 | "version": "1.0.5",
82 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
83 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
84 | "dev": true
85 | },
86 | "has-flag": {
87 | "version": "3.0.0",
88 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
89 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
90 | "dev": true
91 | },
92 | "node-fetch": {
93 | "version": "2.6.1",
94 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
95 | "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
96 | },
97 | "supports-color": {
98 | "version": "5.5.0",
99 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
100 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
101 | "dev": true,
102 | "requires": {
103 | "has-flag": "^3.0.0"
104 | }
105 | },
106 | "tasksfile": {
107 | "version": "5.1.1",
108 | "resolved": "https://registry.npmjs.org/tasksfile/-/tasksfile-5.1.1.tgz",
109 | "integrity": "sha512-G5d3pT8qHgRy3L2zUj+SJMr1C44k2tr+68e1gRxPs6bFHDq/qr3l6BmT2O7OcaGryOHrHIMhwnU3ZTjXGvsXxQ==",
110 | "dev": true,
111 | "requires": {
112 | "@pawelgalazka/cli": "2.0.3",
113 | "@pawelgalazka/shell": "2.0.0",
114 | "chalk": "2.3.0"
115 | },
116 | "dependencies": {
117 | "chalk": {
118 | "version": "2.3.0",
119 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
120 | "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
121 | "dev": true,
122 | "requires": {
123 | "ansi-styles": "^3.1.0",
124 | "escape-string-regexp": "^1.0.5",
125 | "supports-color": "^4.0.0"
126 | }
127 | },
128 | "has-flag": {
129 | "version": "2.0.0",
130 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
131 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
132 | "dev": true
133 | },
134 | "supports-color": {
135 | "version": "4.5.0",
136 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
137 | "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
138 | "dev": true,
139 | "requires": {
140 | "has-flag": "^2.0.0"
141 | }
142 | }
143 | }
144 | }
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rapidsnark",
3 | "version": "0.0.1",
4 | "description": "Snark implementation in C++",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "task": "node ./tasksfile.js"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.io/iden3/rapidsnark"
13 | },
14 | "keywords": [
15 | "snark",
16 | "prover",
17 | "ethereum",
18 | "rollup",
19 | "zksnark",
20 | "zero",
21 | "knowledge",
22 | "fast"
23 | ],
24 | "author": "Jordi Baylina",
25 | "license": "GPL-3.0",
26 | "devDependencies": {
27 | "tasksfile": "^5.1.1"
28 | },
29 | "dependencies": {
30 | "node-fetch": "^2.6.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/service/README.md:
--------------------------------------------------------------------------------
1 | # RapidSnark as a Service
2 |
3 | This folder contains the config file to use `proverServer` as a service
4 | at Linux, with `systemd`.
5 |
6 | Just copy the file `rapidsnark.service` to `/etc/systemd/system/rapidsnark.service`
7 | and update the `ExecStart` parameter with the correct path for binary, `.dat` file
8 | and `.zkey` file.
9 |
10 | After save the file run:
11 |
12 | ```
13 | $ sudo systemctl daemon-reload
14 | ```
15 |
16 | And you can
17 |
18 | ```
19 | $ sudo service rapidsnark start | stop | reload | status
20 | ```
21 |
22 |
--------------------------------------------------------------------------------
/service/rapidsnark.service:
--------------------------------------------------------------------------------
1 | [Unit]
2 | Description=RapidSnark
3 | StartLimitIntervalSec=600
4 |
5 | [Service]
6 | Type=simple
7 | Restart=always
8 | RestartSec=50
9 | ExecStart=/home/ubuntu/rapidsnark/build/proverServer400 /home/ubuntu/circuit-400-32-256-64.dat /home/ubuntu/circuit-400-32-256-64_hez4_final.zkey
10 | KillMode=process
11 | StandardOutput=append:/home/ubuntu/proverServer400.log
12 | StandardError=append:/home/ubuntu/proverServer400.log
13 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | link_libraries(${GMP_LIB})
2 |
3 | add_definitions(${GMP_DEFINIONS})
4 |
5 | if(USE_ASM)
6 | if(ARCH MATCHES "arm64")
7 | add_definitions(-DUSE_ASM -DARCH_ARM64)
8 | elseif(ARCH MATCHES "x86_64")
9 | add_definitions(-DUSE_ASM -DARCH_X86_64)
10 | endif()
11 | endif()
12 |
13 | if(DEFINED BITS_PER_CHUNK)
14 | add_definitions(-DMSM_BITS_PER_CHUNK=${BITS_PER_CHUNK})
15 | endif()
16 |
17 | if(USE_ASM AND ARCH MATCHES "x86_64")
18 |
19 | if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" AND NOT TARGET_PLATFORM MATCHES "^android(_x86_64)?")
20 | set(NASM_FLAGS -fmacho64 --prefix _)
21 | else()
22 | set(NASM_FLAGS -felf64 -DPIC)
23 | endif()
24 |
25 | add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/build/fq_asm.o
26 | COMMAND nasm ${NASM_FLAGS} fq.asm -o fq_asm.o
27 | DEPENDS ${CMAKE_SOURCE_DIR}/build/fq.asm
28 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
29 |
30 | add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/build/fr_asm.o
31 | COMMAND nasm ${NASM_FLAGS} fr.asm -o fr_asm.o
32 | DEPENDS ${CMAKE_SOURCE_DIR}/build/fr.asm
33 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
34 | endif()
35 |
36 | set(FR_SOURCES
37 | ../build/fr.hpp
38 | ../build/fr.cpp
39 | )
40 |
41 | if(USE_ASM)
42 | if(ARCH MATCHES "arm64")
43 | set(FR_SOURCES ${FR_SOURCES} ../build/fr_raw_arm64.s ../build/fr_raw_generic.cpp ../build/fr_generic.cpp)
44 | elseif(ARCH MATCHES "x86_64")
45 | set(FR_SOURCES ${FR_SOURCES} ../build/fr_asm.o)
46 | endif()
47 | else()
48 | set(FR_SOURCES ${FR_SOURCES} ../build/fr_generic.cpp ../build/fr_raw_generic.cpp)
49 | endif()
50 |
51 | add_library(fr STATIC ${FR_SOURCES})
52 | set_target_properties(fr PROPERTIES POSITION_INDEPENDENT_CODE ON)
53 |
54 | link_libraries(fr)
55 |
56 | set(FQ_SOURCES
57 | ../build/fq.hpp
58 | ../build/fq.cpp
59 | )
60 |
61 | if(USE_ASM)
62 | if(ARCH MATCHES "arm64")
63 | set(FQ_SOURCES ${FQ_SOURCES} ../build/fq_raw_arm64.s ../build/fq_raw_generic.cpp ../build/fq_generic.cpp)
64 | elseif(ARCH MATCHES "x86_64")
65 | set(FQ_SOURCES ${FQ_SOURCES} ../build/fq_asm.o)
66 | endif()
67 | else()
68 | set(FQ_SOURCES ${FQ_SOURCES} ../build/fq_raw_generic.cpp ../build/fq_generic.cpp)
69 | endif()
70 |
71 | add_library(fq STATIC ${FQ_SOURCES})
72 | set_target_properties(fq PROPERTIES POSITION_INDEPENDENT_CODE ON)
73 |
74 | link_libraries(fq)
75 |
76 |
77 | if(OpenMP_CXX_FOUND)
78 | add_definitions(-DUSE_OPENMP)
79 | add_compile_options(${OpenMP_CXX_FLAGS})
80 | endif()
81 |
82 | set(LIB_SOURCES
83 | binfile_utils.hpp
84 | binfile_utils.cpp
85 | zkey_utils.hpp
86 | zkey_utils.cpp
87 | wtns_utils.hpp
88 | wtns_utils.cpp
89 | logger.hpp
90 | logger.cpp
91 | fileloader.cpp
92 | fileloader.hpp
93 | prover.cpp
94 | prover.h
95 | verifier.cpp
96 | verifier.h
97 | ../depends/ffiasm/c/misc.cpp
98 | ../depends/ffiasm/c/naf.cpp
99 | ../depends/ffiasm/c/splitparstr.cpp
100 | ../depends/ffiasm/c/alt_bn128.cpp
101 | )
102 |
103 | if(USE_LOGGER)
104 | set(LIB_SOURCES ${LIB_SOURCES} logger.cpp)
105 | add_definitions(-DUSE_LOGGER)
106 | endif()
107 |
108 | include_directories(
109 | ../src
110 | ../build
111 | ../depends/ffiasm/c
112 | ../depends/json/single_include)
113 |
114 | add_library(rapidsnarkStatic STATIC ${LIB_SOURCES})
115 | set_target_properties(rapidsnarkStatic PROPERTIES OUTPUT_NAME rapidsnark)
116 |
117 | add_library(rapidsnarkStaticFrFq STATIC ${LIB_SOURCES} ${FQ_SOURCES} ${FR_SOURCES})
118 | set_target_properties(rapidsnarkStaticFrFq PROPERTIES POSITION_INDEPENDENT_CODE ON)
119 | set_target_properties(rapidsnarkStaticFrFq PROPERTIES OUTPUT_NAME rapidsnark-fr-fq)
120 |
121 | add_executable(prover main_prover.cpp)
122 | target_link_libraries(prover rapidsnarkStatic)
123 |
124 | add_executable(verifier main_verifier.cpp)
125 | target_link_libraries(verifier rapidsnarkStatic)
126 |
127 | add_library(rapidsnark SHARED ${LIB_SOURCES})
128 |
129 | if((USE_LOGGER OR NOT USE_OPENMP) AND NOT TARGET_PLATFORM MATCHES "android")
130 | target_link_libraries(prover pthread)
131 | target_link_libraries(verifier pthread)
132 | endif()
133 |
134 | if(USE_SODIUM)
135 | target_link_libraries(prover sodium)
136 | endif()
137 |
138 | option(BUILD_TESTS "Build the tests" ON)
139 |
140 | if(BUILD_TESTS)
141 | enable_testing()
142 | add_executable(test_public_size test_public_size.c)
143 | target_link_libraries(test_public_size rapidsnarkStaticFrFq pthread)
144 | add_test(NAME test_public_size COMMAND test_public_size circuit_final.zkey 86
145 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/testdata)
146 | endif()
147 |
148 | if(OpenMP_CXX_FOUND)
149 |
150 | if(TARGET_PLATFORM MATCHES "android")
151 | target_link_libraries(prover -static-openmp -fopenmp)
152 | target_link_libraries(verifier -static-openmp -fopenmp)
153 | target_link_libraries(rapidsnark -static-openmp -fopenmp)
154 |
155 | elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
156 | target_link_libraries(prover OpenMP::OpenMP_CXX)
157 | target_link_libraries(verifier OpenMP::OpenMP_CXX)
158 | target_link_libraries(test_public_size OpenMP::OpenMP_CXX)
159 | endif()
160 |
161 | endif()
162 |
163 |
164 | add_executable(test_prover test_prover.cpp)
165 |
--------------------------------------------------------------------------------
/src/binfile_utils.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "binfile_utils.hpp"
11 | #include "fileloader.hpp"
12 |
13 | namespace BinFileUtils {
14 |
15 | BinFile::BinFile(const std::string& fileName, const std::string& _type, uint32_t maxVersion)
16 | : fileLoader(fileName)
17 | {
18 | addr = fileLoader.dataBuffer();
19 | size = fileLoader.dataSize();
20 |
21 | readFileData(_type, maxVersion);
22 | }
23 |
24 | BinFile::BinFile(const void *fileData, size_t fileSize, std::string _type, uint32_t maxVersion) {
25 |
26 | addr = fileData;
27 | size = fileSize;
28 |
29 | readFileData(_type, maxVersion);
30 | }
31 |
32 | void BinFile::readFileData(std::string _type, uint32_t maxVersion) {
33 |
34 | const u_int64_t headerSize = 12;
35 | const u_int64_t minSectionSize = 12;
36 |
37 | if (size < headerSize) {
38 | throw std::range_error("File is too short.");
39 | }
40 |
41 | type.assign((const char *)addr, 4);
42 | pos = 4;
43 |
44 | if (type != _type) {
45 | throw std::invalid_argument("Invalid file type. It should be " + _type + " and it is " + type);
46 | }
47 |
48 | version = readU32LE();
49 | if (version > maxVersion) {
50 | throw std::invalid_argument("Invalid version. It should be <=" + std::to_string(maxVersion) + " and it is " + std::to_string(version));
51 | }
52 |
53 | u_int32_t nSections = readU32LE();
54 |
55 | if (size < headerSize + nSections * minSectionSize) {
56 | throw std::range_error("File is too short to contain " + std::to_string(nSections) + " sections.");
57 | }
58 |
59 | for (u_int32_t i=0; i()));
65 | }
66 |
67 | sections[sType].push_back(Section( (void *)((u_int64_t)addr + pos), sSize));
68 |
69 | pos += sSize;
70 |
71 | if (pos > size) {
72 | throw std::range_error("Section #" + std::to_string(i) + " is invalid."
73 | ". It ends at pos " + std::to_string(pos) +
74 | " but should end before " + std::to_string(size) + ".");
75 | }
76 | }
77 |
78 | pos = 0;
79 | readingSection = nullptr;
80 | }
81 |
82 |
83 | void BinFile::startReadSection(u_int32_t sectionId, u_int32_t sectionPos) {
84 |
85 | if (sections.find(sectionId) == sections.end()) {
86 | throw std::range_error("Section does not exist: " + std::to_string(sectionId));
87 | }
88 |
89 | if (sectionPos >= sections[sectionId].size()) {
90 | throw std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos));
91 | }
92 |
93 | if (readingSection != nullptr) {
94 | throw std::range_error("Already reading a section");
95 | }
96 |
97 | pos = (u_int64_t)(sections[sectionId][sectionPos].start) - (u_int64_t)addr;
98 |
99 | readingSection = §ions[sectionId][sectionPos];
100 | }
101 |
102 | void BinFile::endReadSection(bool check) {
103 | if (check) {
104 | if ((u_int64_t)addr + pos - (u_int64_t)(readingSection->start) != readingSection->size) {
105 | throw std::range_error("Invalid section size");
106 | }
107 | }
108 | readingSection = nullptr;
109 | }
110 |
111 | void *BinFile::getSectionData(u_int32_t sectionId, u_int32_t sectionPos) {
112 |
113 | if (sections.find(sectionId) == sections.end()) {
114 | throw std::range_error("Section does not exist: " + std::to_string(sectionId));
115 | }
116 |
117 | if (sectionPos >= sections[sectionId].size()) {
118 | throw std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos));
119 | }
120 |
121 | return sections[sectionId][sectionPos].start;
122 | }
123 |
124 | u_int64_t BinFile::getSectionSize(u_int32_t sectionId, u_int32_t sectionPos) {
125 |
126 | if (sections.find(sectionId) == sections.end()) {
127 | throw std::range_error("Section does not exist: " + std::to_string(sectionId));
128 | }
129 |
130 | if (sectionPos >= sections[sectionId].size()) {
131 | throw std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos));
132 | }
133 |
134 | return sections[sectionId][sectionPos].size;
135 | }
136 |
137 | u_int32_t BinFile::readU32LE() {
138 | const u_int64_t new_pos = pos + 4;
139 |
140 | if (new_pos > size) {
141 | throw std::range_error("File pos is too big. There are " + std::to_string(size) + " bytes and it's trying to access byte " + std::to_string(new_pos));
142 | }
143 |
144 | u_int32_t res = *((u_int32_t *)((u_int64_t)addr + pos));
145 | pos = new_pos;
146 | return res;
147 | }
148 |
149 | u_int64_t BinFile::readU64LE() {
150 | const u_int64_t new_pos = pos + 8;
151 |
152 | if (new_pos > size) {
153 | throw std::range_error("File pos is too big. There are " + std::to_string(size) + " bytes and it's trying to access byte " + std::to_string(new_pos));
154 | }
155 |
156 | u_int64_t res = *((u_int64_t *)((u_int64_t)addr + pos));
157 | pos = new_pos;
158 | return res;
159 | }
160 |
161 | void *BinFile::read(u_int64_t len) {
162 | const u_int64_t new_pos = pos + len;
163 |
164 | if (new_pos > size) {
165 | throw std::range_error("File pos is too big. There are " + std::to_string(size) + " bytes and it's trying to access byte " + std::to_string(new_pos));
166 | }
167 |
168 | void *res = (void *)((u_int64_t)addr + pos);
169 | pos = new_pos;
170 | return res;
171 | }
172 |
173 | std::unique_ptr openExisting(const std::string& filename, const std::string& type, uint32_t maxVersion) {
174 | return std::unique_ptr(new BinFile(filename, type, maxVersion));
175 | }
176 |
177 | } // Namespace
178 |
179 |
--------------------------------------------------------------------------------
/src/binfile_utils.hpp:
--------------------------------------------------------------------------------
1 | #ifndef BINFILE_UTILS_H
2 | #define BINFILE_UTILS_H
3 | #include
4 | #include