mirror of
https://github.com/logos-blockchain/logos-blockchain-circuits.git
synced 2026-01-02 13:13:08 +00:00
Migrate circuits from nomos-pocs.
This commit is contained in:
parent
5ef0cfbd6c
commit
37570240e6
128
.github/actions/compile-and-bundle/action.yml
vendored
Normal file
128
.github/actions/compile-and-bundle/action.yml
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
name: "Compile and Bundle Circuit"
|
||||
description: "Compiles and bundles the witness generator of a Circom Circuit"
|
||||
branding:
|
||||
icon: "package"
|
||||
color: "blue"
|
||||
|
||||
inputs:
|
||||
circuit-name-display:
|
||||
description: "The name of the Circom circuit to compile."
|
||||
required: true
|
||||
circuit-name-binary:
|
||||
description: "The final name of the compiled binary. The name should be extensionless."
|
||||
required: true
|
||||
circuit-path:
|
||||
description: "The path to the Circom circuit file relative to the repository root."
|
||||
required: true
|
||||
resources-path:
|
||||
description: "The path to the CI resources directory relative to the repository root."
|
||||
required: false
|
||||
default: ".github/resources"
|
||||
version:
|
||||
description: "The version of the bundle. E.g.: v1.0.0."
|
||||
required: true
|
||||
os:
|
||||
description: "The target operating system for the bundle (linux, windows, macos)."
|
||||
required: true
|
||||
arch:
|
||||
description: "The target architecture for the bundle (x86_64, aarch64)."
|
||||
required: true
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Parse Circuit Path
|
||||
id: parse-circuit-path
|
||||
shell: bash
|
||||
env:
|
||||
CIRCUIT_PATH: ${{ inputs.circuit-path }}
|
||||
BUNDLE_TRIPLET: ${{ inputs.version }}-${{ inputs.os }}-${{ inputs.arch }}
|
||||
CIRCUIT_NAME_BINARY: ${{ inputs.circuit-name-binary }}
|
||||
RESOURCES_PATH: ${{ inputs.resources-path }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: |
|
||||
CIRCUIT_DIRECTORY="$(dirname ${CIRCUIT_PATH})"
|
||||
CIRCUIT_FILENAME="$(basename ${CIRCUIT_PATH})"
|
||||
CIRCUIT_FILESTEM="${CIRCUIT_FILENAME%.circom}"
|
||||
CIRCUIT_CPP_DIRNAME="${CIRCUIT_FILESTEM}_cpp"
|
||||
|
||||
platform_binary_name="${CIRCUIT_NAME_BINARY}"
|
||||
if [ "${OS}" = "windows" ]; then
|
||||
platform_binary_name="${platform_binary_name}.exe"
|
||||
fi
|
||||
|
||||
{
|
||||
echo "CIRCUIT_DIRECTORY=${CIRCUIT_DIRECTORY}"
|
||||
echo "CIRCUIT_FILENAME=${CIRCUIT_FILENAME}"
|
||||
echo "CIRCUIT_FILESTEM=${CIRCUIT_FILESTEM}"
|
||||
echo "CIRCUIT_CPP_DIRNAME=${CIRCUIT_CPP_DIRNAME}"
|
||||
echo "CIRCUIT_CPP_PATH=${CIRCUIT_DIRECTORY}/${CIRCUIT_CPP_DIRNAME}"
|
||||
echo "WITNESS_GENERATOR_RESOURCES_PATH=${RESOURCES_PATH}/witness-generator"
|
||||
echo "BUNDLE_TRIPLET=${BUNDLE_TRIPLET}"
|
||||
echo "PLATFORM_BINARY_NAME=${platform_binary_name}"
|
||||
} >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Generate ${{ inputs.circuit-name-display }}
|
||||
shell: bash
|
||||
working-directory: ${{ steps.parse-circuit-path.outputs.CIRCUIT_DIRECTORY }}
|
||||
env:
|
||||
CIRCUIT_FILENAME: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILENAME }}
|
||||
run: circom --c --r1cs --no_asm --O2 "${CIRCUIT_FILENAME}"
|
||||
|
||||
# TODO: Instead of replace, make a fork that generates the appropriate Makefile
|
||||
- name: Replace ${{ inputs.circuit-name-display }}'s Makefile
|
||||
shell: bash
|
||||
env:
|
||||
WITNESS_GENERATOR_RESOURCES_PATH: ${{ steps.parse-circuit-path.outputs.WITNESS_GENERATOR_RESOURCES_PATH }}
|
||||
CIRCUIT_CPP_PATH: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
run: cp "${WITNESS_GENERATOR_RESOURCES_PATH}/Makefile" "${CIRCUIT_CPP_PATH}/Makefile"
|
||||
|
||||
# TODO: Instead of insertion, make a fork that includes the appropriate patch (or the actual fix)
|
||||
- name: Patch MacOS GMP
|
||||
shell: bash
|
||||
if: ${{ inputs.os == 'macos' }}
|
||||
env:
|
||||
WITNESS_GENERATOR_RESOURCES_PATH: ${{ steps.parse-circuit-path.outputs.WITNESS_GENERATOR_RESOURCES_PATH }}
|
||||
CIRCUIT_CPP_PATH: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: cp "${WITNESS_GENERATOR_RESOURCES_PATH}/${{ env.OS }}.gmp_patch.hpp" "${CIRCUIT_CPP_PATH}/gmp_patch.hpp"
|
||||
|
||||
- name: Compile ${{ inputs.circuit-name-display }}
|
||||
if: ${{ inputs.os != 'windows' }}
|
||||
shell: bash
|
||||
working-directory: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
env:
|
||||
CIRCUIT_FILESTEM: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: make PROJECT="${CIRCUIT_FILESTEM}" "${OS}"
|
||||
|
||||
- name: Compile ${{ inputs.circuit-name-display }}
|
||||
if: ${{ inputs.os == 'windows' }}
|
||||
shell: msys2 {0}
|
||||
working-directory: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
env:
|
||||
CIRCUIT_FILESTEM: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: make PROJECT="${CIRCUIT_FILESTEM}" "${OS}"
|
||||
|
||||
- name: Bundle ${{ inputs.circuit-name-display }}
|
||||
shell: bash
|
||||
env:
|
||||
CIRCUIT_NAME: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
PLATFORM_BINARY_NAME: ${{ steps.parse-circuit-path.outputs.PLATFORM_BINARY_NAME }}
|
||||
BUNDLE_NAME: ${{ inputs.circuit-name-binary }}-${{ steps.parse-circuit-path.outputs.BUNDLE_TRIPLET }}
|
||||
WITNESS_GENERATOR_DIR: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/witness-generator"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${WITNESS_GENERATOR_DIR}/${CIRCUIT_NAME}" "$BUNDLE_DIR/${PLATFORM_BINARY_NAME}"
|
||||
mv "${WITNESS_GENERATOR_DIR}/${CIRCUIT_NAME}.dat" "$BUNDLE_DIR/${PLATFORM_BINARY_NAME}.dat"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload ${{ inputs.circuit-name-display }}
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: ${{ inputs.circuit-name-binary }}-${{ steps.parse-circuit-path.outputs.BUNDLE_TRIPLET }}.tar.gz
|
||||
path: ${{ inputs.circuit-name-binary }}-${{ steps.parse-circuit-path.outputs.BUNDLE_TRIPLET }}.tar.gz
|
||||
118
.github/resources/prover/Makefile
vendored
Normal file
118
.github/resources/prover/Makefile
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
###
|
||||
|
||||
EXTRA_CMAKE_FLAGS ?=
|
||||
LIBGOMP_A := $(shell $(CXX) --print-file-name=libgomp.a)
|
||||
|
||||
#Build targets
|
||||
# Add EXTRA_CMAKE_FLAGS
|
||||
host:
|
||||
rm -rf build_prover && mkdir build_prover && cd build_prover && \
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=../package \
|
||||
$(EXTRA_CMAKE_FLAGS) && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
host_linux_x86_64_static:
|
||||
rm -rf build_prover && mkdir build_prover && cd build_prover && \
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=../package \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-static -static-libstdc++ -static-libgcc -no-pie" \
|
||||
-DOpenMP_gomp_LIBRARY=$(LIBGOMP_A) \
|
||||
-DCMAKE_PREFIX_PATH=depends/gmp/package && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
host_windows_x86_64_static:
|
||||
rm -rf build_prover && mkdir build_prover && cd build_prover && \
|
||||
cmake .. \
|
||||
-DUSE_ASM=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=../package \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-static -static-libstdc++ -static-libgcc -L/lib -lmman" \
|
||||
-DCMAKE_CXX_FLAGS="-I/include -include mman_patch.hpp -include cstdint -Duint=unsigned\ int -Du_int32_t=uint32_t -Du_int64_t=uint64_t" && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
host_noasm:
|
||||
rm -rf build_prover_noasm && mkdir build_prover_noasm && cd build_prover_noasm && \
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_noasm -DUSE_ASM=NO && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
host_arm64:
|
||||
rm -rf build_prover_arm64 && mkdir build_prover_arm64 && cd build_prover_arm64 && \
|
||||
cmake .. -DTARGET_PLATFORM=aarch64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_arm64 && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
android:
|
||||
rm -rf build_prover_android && mkdir build_prover_android && cd build_prover_android && \
|
||||
cmake .. -DTARGET_PLATFORM=ANDROID -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android -DBUILD_TESTS=OFF -DUSE_OPENMP=OFF && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
android_openmp:
|
||||
rm -rf build_prover_android_openmp && mkdir build_prover_android_openmp && cd build_prover_android_openmp && \
|
||||
cmake .. -DTARGET_PLATFORM=ANDROID -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_openmp -DBUILD_TESTS=OFF -DUSE_OPENMP=ON && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
android_x86_64:
|
||||
rm -rf build_prover_android_x86_64 && mkdir build_prover_android_x86_64 && cd build_prover_android_x86_64 && \
|
||||
cmake .. -DTARGET_PLATFORM=ANDROID_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_x86_64 -DBUILD_TESTS=OFF -DUSE_OPENMP=OFF && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
android_openmp_x86_64:
|
||||
rm -rf build_prover_android_openmp_x86_64 && mkdir build_prover_android_openmp_x86_64 && cd build_prover_android_openmp_x86_64 && \
|
||||
cmake .. -DTARGET_PLATFORM=ANDROID_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_openmp_x86_64 -DBUILD_TESTS=OFF -DUSE_OPENMP=ON && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
ios:
|
||||
@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
|
||||
rm -rf build_prover_ios && mkdir build_prover_ios && cd build_prover_ios && \
|
||||
cmake .. -GXcode -DTARGET_PLATFORM=IOS -DCMAKE_INSTALL_PREFIX=../package_ios && \
|
||||
xcodebuild -destination 'generic/platform=iOS' -scheme rapidsnarkStatic -project rapidsnark.xcodeproj -configuration Release && \
|
||||
xcodebuild -destination 'generic/platform=iOS' -scheme rapidsnark -project rapidsnark.xcodeproj -configuration Release CODE_SIGNING_ALLOWED=NO && \
|
||||
cp ../depends/gmp/package_ios_arm64/lib/libgmp.a src/Release-iphoneos && \
|
||||
echo "" && echo "iOS Simulator artifacts built in build_prover_ios/src/Release-iphoneos" && echo ""
|
||||
|
||||
ios_simulator:
|
||||
@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
|
||||
rm -rf build_prover_ios_simulator && mkdir build_prover_ios_simulator && cd build_prover_ios_simulator && \
|
||||
cmake .. -GXcode -DTARGET_PLATFORM=IOS_SIMULATOR -DCMAKE_INSTALL_PREFIX=../package_ios_simulator -DUSE_ASM=NO && \
|
||||
xcodebuild -destination 'generic/platform=iOS Simulator' -scheme rapidsnarkStatic -project rapidsnark.xcodeproj && \
|
||||
xcodebuild -destination 'generic/platform=iOS Simulator' -scheme rapidsnark -project rapidsnark.xcodeproj CODE_SIGNING_ALLOWED=NO ARCHS=arm64 && \
|
||||
cp ../depends/gmp/package_iphone_simulator/lib/libgmp.a src/Debug-iphonesimulator && \
|
||||
echo "" && echo "iOS Simulator artifacts built in build_prover_ios_simulator/src/Debug-iphonesimulator" && echo ""
|
||||
|
||||
macos_arm64:
|
||||
@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
|
||||
rm -rf build_prover_macos_arm64 && mkdir build_prover_macos_arm64 && cd build_prover_macos_arm64 && \
|
||||
cmake .. -DTARGET_PLATFORM=macos_arm64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_macos_arm64 && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
macos_x86_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
|
||||
rm -rf build_prover_macos_x86_64 && mkdir build_prover_macos_x86_64 && cd build_prover_macos_x86_64 && \
|
||||
cmake .. -DTARGET_PLATFORM=macos_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_macos_x86_64 && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
clean:
|
||||
rm -rf build_prover \
|
||||
build_prover_macos_arm64 \
|
||||
build_prover_macos_x86_64 \
|
||||
build_prover_android \
|
||||
build_prover_android_x86_64 \
|
||||
build_prover_ios \
|
||||
build_prover_ios_simulator \
|
||||
package \
|
||||
package_macos_arm64 \
|
||||
package_macos_x86_64 \
|
||||
package_android \
|
||||
package_android_x86_64 \
|
||||
package_ios \
|
||||
package_ios_simulator \
|
||||
depends/gmp/package \
|
||||
depends/gmp/package_macos_arm64 \
|
||||
depends/gmp/package_macos_x86_64 \
|
||||
depends/gmp/package_android_arm64 \
|
||||
depends/gmp/package_android_x86_64 \
|
||||
depends/gmp/package_ios_arm64 \
|
||||
depends/gmp/package_iphone_simulator
|
||||
|
||||
423
.github/resources/prover/windows.build_gmp.sh
vendored
Executable file
423
.github/resources/prover/windows.build_gmp.sh
vendored
Executable file
@ -0,0 +1,423 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
NPROC=8
|
||||
fetch_cmd=$( (type wget > /dev/null 2>&1 && echo "wget") || echo "curl -O" )
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "USAGE: $0 <target>"
|
||||
echo "where target is one of:"
|
||||
echo " ios: build for iOS arm64"
|
||||
echo " ios_simulator: build for iPhone Simulator for arm64/x86_64 (fat binary)"
|
||||
echo " macos: build for macOS for arm64/x86_64 (fat binary)"
|
||||
echo " macos_arm64: build for macOS arm64"
|
||||
echo " macos_x86_64: build for macOS x86_64"
|
||||
echo " android: build for Android arm64"
|
||||
echo " android_x86_64: build for Android x86_64"
|
||||
echo " host: build for this host"
|
||||
echo " host_noasm: build for this host without asm optimizations (e.g. needed for macOS)"
|
||||
echo " aarch64: build for Linux aarch64"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
get_gmp()
|
||||
{
|
||||
GMP_NAME=gmp-6.2.1
|
||||
GMP_ARCHIVE=${GMP_NAME}.tar.xz
|
||||
GMP_URL=https://ftp.gnu.org/gnu/gmp/${GMP_ARCHIVE}
|
||||
|
||||
if [ ! -f ${GMP_ARCHIVE} ]; then
|
||||
|
||||
$fetch_cmd ${GMP_URL}
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d gmp ]; then
|
||||
|
||||
tar -xvf ${GMP_ARCHIVE}
|
||||
mv ${GMP_NAME} gmp
|
||||
fi
|
||||
}
|
||||
|
||||
build_aarch64()
|
||||
{
|
||||
PACKAGE_DIR="$GMP_DIR/package_aarch64"
|
||||
BUILD_DIR=build_aarch64
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "aarch64 package is built already. See $PACKAGE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
export TARGET=aarch64-linux-gnu
|
||||
|
||||
echo $TARGET
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_host()
|
||||
{
|
||||
PACKAGE_DIR="$GMP_DIR/package"
|
||||
BUILD_DIR=build
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "Host package is built already. See $PACKAGE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# The following line is a workaround for the Windows build due to an existing incompatibility with current compiler
|
||||
# when building GMP.
|
||||
CFLAGS="-O2 -std=gnu17" CXXFLAGS="-O2 -std=gnu++17" \
|
||||
../configure --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_host_noasm()
|
||||
{
|
||||
PACKAGE_DIR="$GMP_DIR/package"
|
||||
BUILD_DIR=build
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "Host package is built already. See $PACKAGE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
../configure --prefix="$PACKAGE_DIR" --with-pic --disable-fft --disable-assembly &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_android()
|
||||
{
|
||||
PACKAGE_DIR="$GMP_DIR/package_android_arm64"
|
||||
BUILD_DIR=build_android_arm64
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "Android package is built already. See $PACKAGE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$ANDROID_NDK" ]; then
|
||||
|
||||
echo "ERROR: ANDROID_NDK environment variable is not set."
|
||||
echo " It must be an absolute path to the root directory of Android NDK."
|
||||
echo " For instance /home/test/Android/Sdk/ndk/23.1.7779620"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
|
||||
else
|
||||
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
|
||||
fi
|
||||
|
||||
export TARGET=aarch64-linux-android
|
||||
export API=21
|
||||
|
||||
export AR=$TOOLCHAIN/bin/llvm-ar
|
||||
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
|
||||
export AS=$CC
|
||||
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
|
||||
export LD=$TOOLCHAIN/bin/ld
|
||||
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
|
||||
export STRIP=$TOOLCHAIN/bin/llvm-strip
|
||||
|
||||
echo "$TOOLCHAIN"
|
||||
echo "$TARGET"
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_android_x86_64()
|
||||
{
|
||||
PACKAGE_DIR="$GMP_DIR/package_android_x86_64"
|
||||
BUILD_DIR=build_android_x86_64
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "Android package is built already. See $PACKAGE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -z "$ANDROID_NDK" ]; then
|
||||
|
||||
echo "ERROR: ANDROID_NDK environment variable is not set."
|
||||
echo " It must be an absolute path to the root directory of Android NDK."
|
||||
echo " For instance /home/test/Android/Sdk/ndk/23.1.7779620"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$(uname)" == "Darwin" ]; then
|
||||
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
|
||||
else
|
||||
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
|
||||
fi
|
||||
|
||||
export TARGET=x86_64-linux-android
|
||||
export API=21
|
||||
|
||||
export AR=$TOOLCHAIN/bin/llvm-ar
|
||||
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
|
||||
export AS=$CC
|
||||
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
|
||||
export LD=$TOOLCHAIN/bin/ld
|
||||
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
|
||||
export STRIP=$TOOLCHAIN/bin/llvm-strip
|
||||
|
||||
echo "$TOOLCHAIN"
|
||||
echo $TARGET
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_ios()
|
||||
{
|
||||
PACKAGE_DIR="$GMP_DIR/package_ios_arm64"
|
||||
BUILD_DIR=build_ios_arm64
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "iOS package is built already. See $PACKAGE_DIR"
|
||||
return 1
|
||||
fi
|
||||
|
||||
export SDK="iphoneos"
|
||||
export TARGET=arm64-apple-darwin
|
||||
export MIN_IOS_VERSION=8.0
|
||||
|
||||
export ARCH_FLAGS="-arch arm64 -arch arm64e"
|
||||
export OPT_FLAGS="-O3 -g3 -fembed-bitcode"
|
||||
HOST_FLAGS="${ARCH_FLAGS} -miphoneos-version-min=${MIN_IOS_VERSION} -isysroot $(xcrun --sdk ${SDK} --show-sdk-path)"
|
||||
|
||||
CC=$(xcrun --find --sdk "${SDK}" clang)
|
||||
export CC
|
||||
CXX=$(xcrun --find --sdk "${SDK}" clang++)
|
||||
export CXX
|
||||
CPP=$(xcrun --find --sdk "${SDK}" cpp)
|
||||
export CPP
|
||||
export CFLAGS="${HOST_FLAGS} ${OPT_FLAGS}"
|
||||
export CXXFLAGS="${HOST_FLAGS} ${OPT_FLAGS}"
|
||||
export LDFLAGS="${HOST_FLAGS}"
|
||||
|
||||
echo $TARGET
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft --disable-assembly &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_ios_simulator()
|
||||
{
|
||||
libs=()
|
||||
for ARCH in "arm64" "x86_64"; do
|
||||
case "$ARCH" in
|
||||
"arm64" )
|
||||
echo "Building for iPhone Simulator arm64"
|
||||
ARCH_FLAGS="-arch arm64 -arch arm64e"
|
||||
;;
|
||||
"x86_64" )
|
||||
echo "Building for iPhone Simulator x86_64"
|
||||
ARCH_FLAGS="-arch x86_64"
|
||||
;;
|
||||
* )
|
||||
echo "Incorrect iPhone Simulator arch"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
BUILD_DIR="build_iphone_simulator_${ARCH}"
|
||||
PACKAGE_DIR="$GMP_DIR/package_iphone_simulator_${ARCH}"
|
||||
libs+=("${PACKAGE_DIR}/lib/libgmp.a")
|
||||
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "iPhone Simulator ${ARCH} package is built already. See $PACKAGE_DIR. Skip building this ARCH."
|
||||
continue
|
||||
fi
|
||||
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
../configure --prefix="${PACKAGE_DIR}" \
|
||||
CC="$(xcrun --sdk iphonesimulator --find clang)" \
|
||||
CFLAGS="-O3 -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path) ${ARCH_FLAGS} -fvisibility=hidden -mios-simulator-version-min=8.0" \
|
||||
LDFLAGS="" \
|
||||
--host ${ARCH}-apple-darwin --disable-assembly --enable-static --disable-shared --with-pic &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
|
||||
cd ..
|
||||
done
|
||||
|
||||
mkdir -p "${GMP_DIR}/package_iphone_simulator/lib"
|
||||
lipo "${libs[@]}" -create -output "${GMP_DIR}/package_iphone_simulator/lib/libgmp.a"
|
||||
echo "Wrote universal fat library for iPhone Simulator arm64/x86_64 to ${GMP_DIR}/package_iphone_simulator/lib/libgmp.a"
|
||||
}
|
||||
|
||||
build_macos_arch()
|
||||
{
|
||||
ARCH="$1"
|
||||
case "$ARCH" in
|
||||
"arm64" )
|
||||
ARCH_FLAGS="-arch arm64 -arch arm64e"
|
||||
;;
|
||||
"x86_64" )
|
||||
ARCH_FLAGS="-arch x86_64"
|
||||
;;
|
||||
* )
|
||||
echo "Incorrect arch"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
BUILD_DIR="build_macos_${ARCH}"
|
||||
PACKAGE_DIR="$GMP_DIR/package_macos_${ARCH}"
|
||||
if [ -d "$PACKAGE_DIR" ]; then
|
||||
echo "macOS ${ARCH} package is built already. See $PACKAGE_DIR. Skip building this ARCH."
|
||||
return
|
||||
fi
|
||||
rm -rf "$BUILD_DIR"
|
||||
mkdir "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
../configure --prefix="${PACKAGE_DIR}" \
|
||||
CC="$(xcrun --sdk macosx --find clang)" \
|
||||
CFLAGS="-O3 -isysroot $(xcrun --sdk macosx --show-sdk-path) ${ARCH_FLAGS} -fvisibility=hidden -mmacos-version-min=14.0" \
|
||||
LDFLAGS="" \
|
||||
--host "${ARCH}-apple-darwin" --disable-assembly --enable-static --disable-shared --with-pic &&
|
||||
make -j${NPROC} &&
|
||||
make install
|
||||
cd ..
|
||||
}
|
||||
|
||||
build_macos_fat()
|
||||
{
|
||||
echo "Building for macOS arm64"
|
||||
build_macos_arch "arm64"
|
||||
echo "Building for macOS x86_64"
|
||||
build_macos_arch "x86_64"
|
||||
|
||||
gmp_lib_arm64="$GMP_DIR/package_macos_arm64/lib/libgmp.a"
|
||||
gmp_lib_x86_64="$GMP_DIR/package_macos_x86_64/lib/libgmp.a"
|
||||
gmp_lib_fat="$GMP_DIR/package_macos/lib/libgmp.a"
|
||||
|
||||
mkdir -p "${GMP_DIR}/package_macos/lib"
|
||||
lipo "${gmp_lib_arm64}" "${gmp_lib_x86_64}" -create -output "${gmp_lib_fat}"
|
||||
mkdir -p "${GMP_DIR}/package_macos/include"
|
||||
cp "${GMP_DIR}/package_macos_arm64/include/gmp.h" "${GMP_DIR}/package_macos/include/"
|
||||
echo "Wrote universal fat library for macOS arm64/x86_64 to ${GMP_DIR}/package_macos/lib/libgmp.a"
|
||||
}
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET_PLATFORM=$(echo "$1" | tr "[:upper:]" "[:lower:]")
|
||||
|
||||
cd depends
|
||||
|
||||
get_gmp
|
||||
|
||||
cd gmp
|
||||
|
||||
GMP_DIR=$PWD
|
||||
|
||||
case "$TARGET_PLATFORM" in
|
||||
|
||||
"ios" )
|
||||
echo "Building for ios"
|
||||
build_ios
|
||||
;;
|
||||
|
||||
"ios_simulator" )
|
||||
echo "Building for iPhone Simulator"
|
||||
build_ios_simulator
|
||||
;;
|
||||
|
||||
"macos" )
|
||||
echo "Building fat library for macOS"
|
||||
build_macos_fat
|
||||
;;
|
||||
|
||||
"macos_arm64" )
|
||||
echo "Building library for macOS arm64"
|
||||
build_macos_arch "arm64"
|
||||
;;
|
||||
|
||||
"macos_x86_64" )
|
||||
echo "Building library for macOS x86_64"
|
||||
build_macos_arch "x86_64"
|
||||
;;
|
||||
|
||||
"android" )
|
||||
echo "Building for android"
|
||||
build_android
|
||||
;;
|
||||
|
||||
"android_x86_64" )
|
||||
echo "Building for android x86_64"
|
||||
build_android_x86_64
|
||||
;;
|
||||
|
||||
"host" )
|
||||
echo "Building for this host"
|
||||
build_host
|
||||
;;
|
||||
|
||||
"host_noasm" )
|
||||
echo "Building for this host without asm optimizations (e.g. needed for macOS)"
|
||||
build_host_noasm
|
||||
;;
|
||||
|
||||
"aarch64" )
|
||||
echo "Building for linux aarch64"
|
||||
build_aarch64
|
||||
;;
|
||||
|
||||
* )
|
||||
usage
|
||||
|
||||
esac
|
||||
7
.github/resources/prover/windows.mman_patch.hpp
vendored
Normal file
7
.github/resources/prover/windows.mman_patch.hpp
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
// Workaround for Windows where some mman functions are not defined
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cstddef>
|
||||
inline int madvise(void*, size_t, int) { return 0; }
|
||||
#define MADV_SEQUENTIAL 0
|
||||
#endif
|
||||
181
.github/resources/prover/windows.src-CMakeLists.txt
vendored
Normal file
181
.github/resources/prover/windows.src-CMakeLists.txt
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
# Workaround for CMake on Windows to
|
||||
# Added explicit linking (e.g., mman), which are otherwise resolved transitively on Linux and macOS.
|
||||
|
||||
find_library(MMAN_LIB mman PATHS /lib NO_DEFAULT_PATH REQUIRED)
|
||||
|
||||
link_libraries(${GMP_LIB})
|
||||
|
||||
add_definitions(${GMP_DEFINIONS})
|
||||
|
||||
if(USE_ASM)
|
||||
if(ARCH MATCHES "arm64")
|
||||
add_definitions(-DUSE_ASM -DARCH_ARM64)
|
||||
elseif(ARCH MATCHES "x86_64")
|
||||
add_definitions(-DUSE_ASM -DARCH_X86_64)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(DEFINED BITS_PER_CHUNK)
|
||||
add_definitions(-DMSM_BITS_PER_CHUNK=${BITS_PER_CHUNK})
|
||||
endif()
|
||||
|
||||
if(USE_ASM AND ARCH MATCHES "x86_64")
|
||||
|
||||
if (CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin" AND NOT TARGET_PLATFORM MATCHES "^android(_x86_64)?")
|
||||
set(NASM_FLAGS -fmacho64 --prefix _)
|
||||
else()
|
||||
set(NASM_FLAGS -felf64 -DPIC)
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/build/fq_asm.o
|
||||
COMMAND nasm ${NASM_FLAGS} fq.asm -o fq_asm.o
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/build/fq.asm
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/build/fr_asm.o
|
||||
COMMAND nasm ${NASM_FLAGS} fr.asm -o fr_asm.o
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/build/fr.asm
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
|
||||
endif()
|
||||
|
||||
set(FR_SOURCES
|
||||
../build/fr.hpp
|
||||
../build/fr.cpp
|
||||
)
|
||||
|
||||
if(USE_ASM)
|
||||
if(ARCH MATCHES "arm64")
|
||||
set(FR_SOURCES ${FR_SOURCES} ../build/fr_raw_arm64.s ../build/fr_raw_generic.cpp ../build/fr_generic.cpp)
|
||||
elseif(ARCH MATCHES "x86_64")
|
||||
set(FR_SOURCES ${FR_SOURCES} ../build/fr_asm.o)
|
||||
endif()
|
||||
else()
|
||||
set(FR_SOURCES ${FR_SOURCES} ../build/fr_generic.cpp ../build/fr_raw_generic.cpp)
|
||||
endif()
|
||||
|
||||
add_library(fr STATIC ${FR_SOURCES})
|
||||
set_target_properties(fr PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
link_libraries(fr)
|
||||
|
||||
set(FQ_SOURCES
|
||||
../build/fq.hpp
|
||||
../build/fq.cpp
|
||||
)
|
||||
|
||||
if(USE_ASM)
|
||||
if(ARCH MATCHES "arm64")
|
||||
set(FQ_SOURCES ${FQ_SOURCES} ../build/fq_raw_arm64.s ../build/fq_raw_generic.cpp ../build/fq_generic.cpp)
|
||||
elseif(ARCH MATCHES "x86_64")
|
||||
set(FQ_SOURCES ${FQ_SOURCES} ../build/fq_asm.o)
|
||||
endif()
|
||||
else()
|
||||
set(FQ_SOURCES ${FQ_SOURCES} ../build/fq_raw_generic.cpp ../build/fq_generic.cpp)
|
||||
endif()
|
||||
|
||||
add_library(fq STATIC ${FQ_SOURCES})
|
||||
set_target_properties(fq PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
link_libraries(fq)
|
||||
|
||||
|
||||
if(OpenMP_CXX_FOUND)
|
||||
add_definitions(-DUSE_OPENMP)
|
||||
add_compile_options(${OpenMP_CXX_FLAGS})
|
||||
endif()
|
||||
|
||||
set(LIB_SOURCES
|
||||
binfile_utils.hpp
|
||||
binfile_utils.cpp
|
||||
zkey_utils.hpp
|
||||
zkey_utils.cpp
|
||||
wtns_utils.hpp
|
||||
wtns_utils.cpp
|
||||
logger.hpp
|
||||
logger.cpp
|
||||
fileloader.cpp
|
||||
fileloader.hpp
|
||||
prover.cpp
|
||||
prover.h
|
||||
verifier.cpp
|
||||
verifier.h
|
||||
../depends/ffiasm/c/misc.cpp
|
||||
../depends/ffiasm/c/naf.cpp
|
||||
../depends/ffiasm/c/splitparstr.cpp
|
||||
../depends/ffiasm/c/alt_bn128.cpp
|
||||
)
|
||||
|
||||
if(USE_LOGGER)
|
||||
set(LIB_SOURCES ${LIB_SOURCES} logger.cpp)
|
||||
add_definitions(-DUSE_LOGGER)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
../src
|
||||
../build
|
||||
../depends/ffiasm/c
|
||||
../depends/json/single_include
|
||||
/include
|
||||
)
|
||||
|
||||
add_library(rapidsnarkStatic STATIC ${LIB_SOURCES})
|
||||
set_target_properties(rapidsnarkStatic PROPERTIES OUTPUT_NAME rapidsnark)
|
||||
|
||||
add_library(rapidsnarkStaticFrFq STATIC ${LIB_SOURCES} ${FQ_SOURCES} ${FR_SOURCES})
|
||||
set_target_properties(rapidsnarkStaticFrFq PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(rapidsnarkStaticFrFq PROPERTIES OUTPUT_NAME rapidsnark-fr-fq)
|
||||
|
||||
add_executable(prover main_prover.cpp)
|
||||
target_link_libraries(
|
||||
prover rapidsnarkStatic
|
||||
fr fq ${MMAN_LIB} # Explicit linking
|
||||
)
|
||||
|
||||
add_executable(verifier main_verifier.cpp)
|
||||
target_link_libraries(
|
||||
verifier rapidsnarkStatic
|
||||
fr fq ${MMAN_LIB} # Explicit linking
|
||||
)
|
||||
|
||||
add_library(rapidsnark SHARED ${LIB_SOURCES})
|
||||
target_link_libraries(rapidsnark ${MMAN_LIB}) # Explicit linking
|
||||
|
||||
if((USE_LOGGER OR NOT USE_OPENMP) AND NOT TARGET_PLATFORM MATCHES "android")
|
||||
target_link_libraries(prover pthread)
|
||||
target_link_libraries(verifier pthread)
|
||||
endif()
|
||||
|
||||
if(USE_SODIUM)
|
||||
target_link_libraries(prover sodium)
|
||||
endif()
|
||||
|
||||
option(BUILD_TESTS "Build the tests" ON)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
enable_testing()
|
||||
add_executable(test_public_size test_public_size.c)
|
||||
target_link_libraries(
|
||||
test_public_size rapidsnarkStaticFrFq pthread
|
||||
${MMAN_LIB} # Explicit linking
|
||||
)
|
||||
add_test(NAME test_public_size COMMAND test_public_size circuit_final.zkey 86
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/testdata)
|
||||
endif()
|
||||
|
||||
if(OpenMP_CXX_FOUND)
|
||||
|
||||
if(TARGET_PLATFORM MATCHES "android")
|
||||
target_link_libraries(prover -static-openmp -fopenmp)
|
||||
target_link_libraries(verifier -static-openmp -fopenmp)
|
||||
target_link_libraries(rapidsnark -static-openmp -fopenmp)
|
||||
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_libraries(prover OpenMP::OpenMP_CXX)
|
||||
target_link_libraries(verifier OpenMP::OpenMP_CXX)
|
||||
target_link_libraries(test_public_size OpenMP::OpenMP_CXX)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
add_executable(test_prover test_prover.cpp)
|
||||
19
.github/resources/prover/windows.uio.h
vendored
Normal file
19
.github/resources/prover/windows.uio.h
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Workaround for Windows UIO header, as it's not available by default
|
||||
|
||||
#ifndef SYS_UIO_H
|
||||
#define SYS_UIO_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct iovec
|
||||
{
|
||||
void *iov_base;
|
||||
size_t iov_len;
|
||||
};
|
||||
|
||||
ssize_t readv(int fildes, const struct iovec *iov, int iovcnt);
|
||||
ssize_t writev(int fildes, const struct iovec *iov, int iovcnt);
|
||||
|
||||
#endif
|
||||
|
||||
43
.github/resources/witness-generator/Makefile
vendored
Normal file
43
.github/resources/witness-generator/Makefile
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
.PHONY: linux macos windows build clean
|
||||
|
||||
# ---- Arguments ----
|
||||
ifndef PROJECT
|
||||
$(error PROJECT is not set. Usage: make PROJECT=<name>. E.g.: make PROJECT=pol linux)
|
||||
endif
|
||||
|
||||
# ---- Common ----
|
||||
CXX := g++
|
||||
CXXFLAGS_COMMON := -std=c++11 -O3 -I. -Wno-address-of-packed-member
|
||||
SRCS := main.cpp calcwit.cpp fr.cpp $(PROJECT).cpp
|
||||
OBJS := $(SRCS:.cpp=.o)
|
||||
DEPS_HPP := circom.hpp calcwit.hpp fr.hpp
|
||||
BIN := $(PROJECT)
|
||||
|
||||
# ---- Linux ----
|
||||
linux: CXXFLAGS=$(CXXFLAGS_COMMON)
|
||||
linux: LDFLAGS=-static
|
||||
linux: LDLIBS=-lgmp
|
||||
linux: $(BIN)
|
||||
|
||||
# ---- macOS ----
|
||||
macos: CXXFLAGS=$(CXXFLAGS_COMMON) -I/opt/homebrew/include -include gmp_patch.hpp
|
||||
macos: LDFLAGS=-Wl,-search_paths_first -Wl,-dead_strip
|
||||
macos: LDLIBS=/opt/homebrew/lib/libgmp.a
|
||||
macos: $(BIN)
|
||||
|
||||
# ---- Windows (MinGW) ----
|
||||
windows: CXXFLAGS=$(CXXFLAGS_COMMON) -I/include -Duint="unsigned int"
|
||||
windows: LDFLAGS=-static
|
||||
windows: LDLIBS=-L/lib -lgmp -lmman
|
||||
windows: $(BIN)
|
||||
|
||||
# ---- Rules ----
|
||||
$(BIN): $(OBJS)
|
||||
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
%.o: %.cpp $(DEPS_HPP)
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(BIN)
|
||||
|
||||
150
.github/resources/witness-generator/macos.gmp_patch.hpp
vendored
Normal file
150
.github/resources/witness-generator/macos.gmp_patch.hpp
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
// Workaround for a known macOS issue where certain GMP functions fail to compile
|
||||
// due to strict type checking, despite uint64_t and mp_limb_t being the same size.
|
||||
// These wrappers explicitly cast uint64_t parameters to mp_limb_t to resolve the mismatch.
|
||||
|
||||
#ifndef GMP_PATCH_CAST_HPP
|
||||
#define GMP_PATCH_CAST_HPP
|
||||
|
||||
#include <gmp.h>
|
||||
#include <cstdint>
|
||||
|
||||
// Arithmetic Wrappers
|
||||
inline mp_limb_t gmp_add_n_cast(uint64_t* rp, const uint64_t* up, const uint64_t* vp, mp_size_t n) {
|
||||
return mpn_add_n(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
reinterpret_cast<const mp_limb_t*>(vp),
|
||||
n);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_sub_n_cast(uint64_t* rp, const uint64_t* up, const uint64_t* vp, mp_size_t n) {
|
||||
return mpn_sub_n(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
reinterpret_cast<const mp_limb_t*>(vp),
|
||||
n);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_add_1_cast(uint64_t* rp, const uint64_t* up, mp_size_t n, mp_limb_t b) {
|
||||
return mpn_add_1(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n, b);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_sub_1_cast(uint64_t* rp, const uint64_t* up, mp_size_t n, mp_limb_t b) {
|
||||
return mpn_sub_1(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n, b);
|
||||
}
|
||||
|
||||
inline int gmp_cmp_cast(const uint64_t* up, const uint64_t* vp, mp_size_t n) {
|
||||
return mpn_cmp(reinterpret_cast<const mp_limb_t*>(up),
|
||||
reinterpret_cast<const mp_limb_t*>(vp),
|
||||
n);
|
||||
}
|
||||
|
||||
inline void gmp_copyi_cast(uint64_t* dst, const uint64_t* src, mp_size_t n) {
|
||||
mpn_copyi(reinterpret_cast<mp_limb_t*>(dst),
|
||||
reinterpret_cast<const mp_limb_t*>(src),
|
||||
n);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_mul_1_cast(uint64_t* rp, const uint64_t* up, mp_size_t n, mp_limb_t b) {
|
||||
return mpn_mul_1(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n, b);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_addmul_1_cast(uint64_t* rp, const uint64_t* up, mp_size_t n, mp_limb_t b) {
|
||||
return mpn_addmul_1(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n, b);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_add_cast(uint64_t* rp, const uint64_t* up, mp_size_t un, const uint64_t* vp, mp_size_t vn) {
|
||||
return mpn_add(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up), un,
|
||||
reinterpret_cast<const mp_limb_t*>(vp), vn);
|
||||
}
|
||||
|
||||
// Logic/Bitwise Wrappers
|
||||
inline int gmp_zero_p_cast(const uint64_t* up, mp_size_t n) {
|
||||
return mpn_zero_p(reinterpret_cast<const mp_limb_t*>(up), n);
|
||||
}
|
||||
|
||||
inline void gmp_and_n_cast(uint64_t* rp, const uint64_t* up, const uint64_t* vp, mp_size_t n) {
|
||||
mpn_and_n(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
reinterpret_cast<const mp_limb_t*>(vp),
|
||||
n);
|
||||
}
|
||||
|
||||
inline void gmp_com_cast(uint64_t* rp, const uint64_t* up, mp_size_t n) {
|
||||
mpn_com(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n);
|
||||
}
|
||||
|
||||
inline void gmp_ior_n_cast(uint64_t* rp, const uint64_t* up, const uint64_t* vp, mp_size_t n) {
|
||||
mpn_ior_n(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
reinterpret_cast<const mp_limb_t*>(vp),
|
||||
n);
|
||||
}
|
||||
|
||||
inline void gmp_xor_n_cast(uint64_t* rp, const uint64_t* up, const uint64_t* vp, mp_size_t n) {
|
||||
mpn_xor_n(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
reinterpret_cast<const mp_limb_t*>(vp),
|
||||
n);
|
||||
}
|
||||
|
||||
// Shift Wrappers
|
||||
|
||||
inline mp_limb_t gmp_lshift_cast(uint64_t* rp, const uint64_t* up, mp_size_t n, unsigned int cnt) {
|
||||
return mpn_lshift(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n, cnt);
|
||||
}
|
||||
|
||||
inline mp_limb_t gmp_rshift_cast(uint64_t* rp, const uint64_t* up, mp_size_t n, unsigned int cnt) {
|
||||
return mpn_rshift(reinterpret_cast<mp_limb_t*>(rp),
|
||||
reinterpret_cast<const mp_limb_t*>(up),
|
||||
n, cnt);
|
||||
}
|
||||
|
||||
// Undefine existing GMP macros
|
||||
#undef mpn_add_n
|
||||
#undef mpn_sub_n
|
||||
#undef mpn_add_1
|
||||
#undef mpn_sub_1
|
||||
#undef mpn_cmp
|
||||
#undef mpn_copyi
|
||||
#undef mpn_mul_1
|
||||
#undef mpn_addmul_1
|
||||
#undef mpn_add
|
||||
#undef mpn_zero_p
|
||||
#undef mpn_and_n
|
||||
#undef mpn_com
|
||||
#undef mpn_ior_n
|
||||
#undef mpn_xor_n
|
||||
#undef mpn_lshift
|
||||
#undef mpn_rshift
|
||||
|
||||
// Redefine GMP macros to wrappers
|
||||
#define mpn_add_n gmp_add_n_cast
|
||||
#define mpn_sub_n gmp_sub_n_cast
|
||||
#define mpn_add_1 gmp_add_1_cast
|
||||
#define mpn_sub_1 gmp_sub_1_cast
|
||||
#define mpn_cmp gmp_cmp_cast
|
||||
#define mpn_copyi gmp_copyi_cast
|
||||
#define mpn_mul_1 gmp_mul_1_cast
|
||||
#define mpn_addmul_1 gmp_addmul_1_cast
|
||||
#define mpn_add gmp_add_cast
|
||||
#define mpn_zero_p gmp_zero_p_cast
|
||||
#define mpn_and_n gmp_and_n_cast
|
||||
#define mpn_com gmp_com_cast
|
||||
#define mpn_ior_n gmp_ior_n_cast
|
||||
#define mpn_xor_n gmp_xor_n_cast
|
||||
#define mpn_lshift gmp_lshift_cast
|
||||
#define mpn_rshift gmp_rshift_cast
|
||||
|
||||
#endif // GMP_PATCH_CAST_HPP
|
||||
537
.github/workflows/build-circuits.yml
vendored
Normal file
537
.github/workflows/build-circuits.yml
vendored
Normal file
@ -0,0 +1,537 @@
|
||||
name: Build Circuits
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "circom_circuits-v*.*.*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Tag to release. Must follow the format of 'circom_circuits-vX.Y.Z'."
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Configure Environment
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.define-version.outputs.version }}
|
||||
tag: ${{ steps.define-version.outputs.tag }}
|
||||
steps:
|
||||
- name: Define version
|
||||
id: define-version
|
||||
env:
|
||||
# Use the tag name if it is available, otherwise use the input version.
|
||||
# If neither is available, default to the commit hash.
|
||||
TAG: ${{ (github.ref_type == 'tag' && github.ref_name) || inputs.tag || '' }}
|
||||
run: |
|
||||
if [ -z "$TAG" ]; then
|
||||
echo "Could not determine tag."
|
||||
exit 1
|
||||
elif [[ ! "$TAG" =~ ^circom_circuits-v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "TAG must follow the format of 'circom_circuits-vX.Y.Z'. Value: '$VERSION'."
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Parse Version: Take only the vX.Y.Z part.
|
||||
VERSION=$(echo $TAG | cut -d'-' -f2)
|
||||
|
||||
# Export the tag and version.
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
build-linux:
|
||||
name: Build Linux Binaries (Native)
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
OS: linux
|
||||
ARCH: x86_64
|
||||
steps:
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Setup Dependencies
|
||||
working-directory: circom_circuits/rapidsnark
|
||||
run: sudo apt update -y
|
||||
|
||||
- name: Install Dependencies [Prover]
|
||||
run: sudo apt install -y build-essential cmake libgmp-dev libsodium-dev nasm curl m4
|
||||
|
||||
- name: Install Dependencies [Witness Generator]
|
||||
run: sudo apt install nlohmann-json3-dev
|
||||
|
||||
- name: Replace Prover Makefile # TODO: Make a fork generate the appropriate Linux Makefile
|
||||
run: cp .github/resources/prover/Makefile circom_circuits/rapidsnark/Makefile
|
||||
|
||||
- name: Compile Prover and Verifier
|
||||
working-directory: circom_circuits/rapidsnark
|
||||
run: |
|
||||
./build_gmp.sh host
|
||||
make host_linux_x86_64_static
|
||||
|
||||
- name: Bundle Rapidsnark Prover
|
||||
env:
|
||||
BINARY_NAME: prover
|
||||
BUNDLE_NAME: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}"/bin/${BINARY_NAME} "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Bundle Rapidsnark Verifier
|
||||
env:
|
||||
BINARY_NAME: verifier
|
||||
BUNDLE_NAME: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}"/bin/${BINARY_NAME} "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload Rapidsnark Prover
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Rapidsnark Verifier
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Compile and Bundle PoL
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoL"
|
||||
circuit-name-binary: "pol"
|
||||
circuit-path: "circom_circuits/Mantle/pol.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle PoQ
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoQ"
|
||||
circuit-name-binary: "poq"
|
||||
circuit-path: "circom_circuits/Blend/poq.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle ZKSign
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-path: "circom_circuits/Mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle PoC
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoC"
|
||||
circuit-name-binary: "poc"
|
||||
circuit-path: "circom_circuits/Mantle/poc.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
build-windows:
|
||||
name: Build Windows Binaries (Native)
|
||||
runs-on: windows-latest
|
||||
needs:
|
||||
- setup
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
OS: windows
|
||||
ARCH: x86_64
|
||||
steps:
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2.28.0 # FIXME: Ideally use the hash to avoid supply chain attacks. Currently unable to.
|
||||
with:
|
||||
update: true
|
||||
install: >-
|
||||
base-devel
|
||||
mingw-w64-x86_64-toolchain
|
||||
make
|
||||
git
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
$env:RUSTFLAGS="-A dead_code"; cargo build --release
|
||||
$env:RUSTFLAGS="-A dead_code"; cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install Dependencies [Witness Generator]
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
# nlohmann/json
|
||||
mkdir -p /include/nlohmann/
|
||||
wget -O /include/nlohmann/json.hpp https://github.com/nlohmann/json/releases/download/v3.12.0/json.hpp
|
||||
|
||||
# mman-win32
|
||||
git clone https://github.com/alitrack/mman-win32.git
|
||||
pushd mman-win32
|
||||
./configure --prefix= # Path: /
|
||||
make
|
||||
make install
|
||||
popd
|
||||
|
||||
- name: Install Dependencies [Prover]
|
||||
shell: msys2 {0}
|
||||
run: pacman --noconfirm -Sy --needed cmake nasm mingw-w64-ucrt-x86_64-libsodium
|
||||
|
||||
- name: Replace Prover Makefile # TODO: Make a fork generate the appropriate Windows Makefile
|
||||
shell: msys2 {0}
|
||||
run: cp .github/resources/prover/Makefile circom_circuits/rapidsnark/Makefile
|
||||
|
||||
- name: Replace Prover CMakeLists
|
||||
shell: msys2 {0}
|
||||
run: cp .github/resources/prover/${{ env.OS }}.src-CMakeLists.txt circom_circuits/rapidsnark/src/CMakeLists.txt
|
||||
|
||||
- name: Patch Windows mman
|
||||
shell: msys2 {0}
|
||||
run: cp .github/resources/prover/${{ env.OS }}.mman_patch.hpp /include/mman_patch.hpp
|
||||
|
||||
- name: Add uio.h headers
|
||||
shell: msys2 {0}
|
||||
run: cp .github/resources/prover/${{ env.OS }}.uio.h /include/sys/uio.h
|
||||
|
||||
- name: Replace build_gmp
|
||||
shell: msys2 {0}
|
||||
run: cp .github/resources/prover/${{ env.OS }}.build_gmp.sh circom_circuits/rapidsnark/build_gmp.sh
|
||||
|
||||
- name: Compile Prover and Verifier
|
||||
shell: msys2 {0}
|
||||
working-directory: circom_circuits/rapidsnark
|
||||
run: |
|
||||
./build_gmp.sh host
|
||||
make host_windows_x86_64_static
|
||||
|
||||
- name: Bundle Rapidsnark Prover
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
BINARY_NAME: prover
|
||||
BUNDLE_NAME: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}"/bin/${BINARY_NAME}.exe "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Bundle Rapidsnark Verifier
|
||||
shell: msys2 {0}
|
||||
env:
|
||||
BINARY_NAME: verifier
|
||||
BUNDLE_NAME: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}"/bin/${BINARY_NAME}.exe "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload Rapidsnark Prover
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Rapidsnark Verifier
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Compile and Bundle PoL
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoL"
|
||||
circuit-name-binary: "pol"
|
||||
circuit-path: "circom_circuits/Mantle/pol.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle PoQ
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoQ"
|
||||
circuit-name-binary: "poq"
|
||||
circuit-path: "circom_circuits/Blend/poq.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle ZKSign
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-path: "circom_circuits/Mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle PoC
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoC"
|
||||
circuit-name-binary: "poc"
|
||||
circuit-path: "circom_circuits/Mantle/poc.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
build-macos:
|
||||
name: Build MacOS Binaries (Native)
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- setup
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
ARCH: aarch64
|
||||
OS: macos
|
||||
steps:
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Setup Dependencies
|
||||
run: mkdir include
|
||||
|
||||
- name: Install Dependencies [Witness Generator]
|
||||
run: brew install nlohmann-json
|
||||
|
||||
- name: Install Dependencies [Prover]
|
||||
run: brew install nasm m4
|
||||
|
||||
- name: Compile Prover and Verifier
|
||||
working-directory: circom_circuits/rapidsnark
|
||||
run: |
|
||||
./build_gmp.sh macos_arm64
|
||||
make macos_arm64
|
||||
|
||||
- name: Bundle Rapidsnark Prover
|
||||
env:
|
||||
BINARY_NAME: prover
|
||||
BUNDLE_NAME: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package_macos_arm64
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}/bin/${BINARY_NAME}" "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Bundle Rapidsnark Verifier
|
||||
env:
|
||||
BINARY_NAME: verifier
|
||||
BUNDLE_NAME: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package_macos_arm64
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}/bin/${BINARY_NAME}" "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload Rapidsnark Prover
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Rapidsnark Verifier
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Compile and Bundle PoL
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoL"
|
||||
circuit-name-binary: "pol"
|
||||
circuit-path: "circom_circuits/Mantle/pol.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle PoQ
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoQ"
|
||||
circuit-name-binary: "poq"
|
||||
circuit-path: "circom_circuits/Blend/poq.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle ZKSign
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-path: "circom_circuits/Mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile and Bundle PoC
|
||||
uses: ./.github/actions/compile-and-bundle
|
||||
with:
|
||||
circuit-name-display: "PoC"
|
||||
circuit-name-binary: "poc"
|
||||
circuit-path: "circom_circuits/Mantle/poc.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
publish-release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
- build-linux
|
||||
- build-windows
|
||||
- build-macos
|
||||
env:
|
||||
TAG: ${{ needs.setup.outputs.tag }}
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
outputs:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
steps:
|
||||
- name: Create Release
|
||||
uses: actions/create-release@4c11c9fe1dcd9636620a16455165783b20fc7ea0
|
||||
id: create_release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ env.TAG }}
|
||||
release_name: Circom Circuits ${{ env.VERSION }}
|
||||
body: |
|
||||
This is a release of Circom Circuits ${{ env.VERSION }}.
|
||||
## Changelog
|
||||
- feature(X): new feature
|
||||
- fix(Y): bug description
|
||||
- feature: performance improvement on Z
|
||||
## Checklist
|
||||
Before publishing please ensure:
|
||||
- [ ] Description is complete
|
||||
- [ ] Changelog is correct
|
||||
- [ ] Assets for all platforms exist
|
||||
- [ ] Pre-release is checked if necessary
|
||||
- [ ] Remove this checklist before publishing the release.
|
||||
draft: true
|
||||
prerelease: true
|
||||
|
||||
upload-artifacts:
|
||||
name: Upload Artifacts to Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
- publish-release
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- os: linux
|
||||
arch: x86_64
|
||||
- os: macos
|
||||
arch: aarch64
|
||||
- os: windows
|
||||
arch: x86_64
|
||||
artifact:
|
||||
- prover
|
||||
- verifier
|
||||
- pol
|
||||
- poq
|
||||
- zksign
|
||||
- poc
|
||||
env:
|
||||
UPLOAD_URL: ${{ needs.publish-release.outputs.upload_url }}
|
||||
ARTIFACT_NAME: ${{ matrix.artifact }}-${{ needs.setup.outputs.version }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}.tar.gz
|
||||
steps:
|
||||
- name: Download Artifacts
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: ${{ env.ARTIFACT_NAME }}
|
||||
|
||||
- name: Upload Artifacts to Release
|
||||
uses: actions/upload-release-asset@ef2adfe8cb8ebfa540930c452c576b3819990faa
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ env.UPLOAD_URL }}
|
||||
asset_path: ${{ env.ARTIFACT_NAME }}
|
||||
asset_name: ${{ env.ARTIFACT_NAME }}
|
||||
asset_content_type: application/octet-stream
|
||||
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "circomlib"]
|
||||
path = circom_circuits/circomlib
|
||||
url = https://github.com/iden3/circomlib.git
|
||||
[submodule "rapidsnark"]
|
||||
path = circom_circuits/rapidsnark
|
||||
url = https://github.com/iden3/rapidsnark
|
||||
331
blend/generate_inputs_for_poq.py
Normal file
331
blend/generate_inputs_for_poq.py
Normal file
@ -0,0 +1,331 @@
|
||||
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [
|
||||
0x1a1d063e54b1e764b63e1855bff015b8cedd192f47308731499573f23597d4b5,
|
||||
0x26abc66f3fdf8e68839d10956259063708235dccc1aa3793b91b002c5b257c37,
|
||||
0x0c7c64a9d887385381a578cfed5aed370754427aabca92a70b3c2b12ff4d7be8,
|
||||
0x1cf5998769e9fab79e17f0b6d08b2d1eba2ebac30dc386b0edd383831354b495,
|
||||
0x0f5e3a8566be31b7564ca60461e9e08b19828764a9669bc17aba0b97e66b0109,
|
||||
0x18df6a9d19ea90d895e60e4db0794a01f359a53a180b7d4b42bf3d7a531c976e,
|
||||
0x04f7bf2c5c0538ac6e4b782c3c6e601ad0ea1d3a3b9d25ef4e324055fa3123dc,
|
||||
0x29c76ce22255206e3c40058523748531e770c0584aa2328ce55d54628b89ebe6,
|
||||
0x198d425a45b78e85c053659ab4347f5d65b1b8e9c6108dbe00e0e945dbc5ff15,
|
||||
0x25ee27ab6296cd5e6af3cc79c598a1daa7ff7f6878b3c49d49d3a9a90c3fdf74,
|
||||
0x138ea8e0af41a1e024561001c0b6eb1505845d7d0c55b1b2c0f88687a96d1381,
|
||||
0x306197fb3fab671ef6e7c2cba2eefd0e42851b5b9811f2ca4013370a01d95687,
|
||||
0x1a0c7d52dc32a4432b66f0b4894d4f1a21db7565e5b4250486419eaf00e8f620,
|
||||
0x2b46b418de80915f3ff86a8e5c8bdfccebfbe5f55163cd6caa52997da2c54a9f,
|
||||
0x12d3e0dc0085873701f8b777b9673af9613a1af5db48e05bfb46e312b5829f64,
|
||||
0x263390cf74dc3a8870f5002ed21d089ffb2bf768230f648dba338a5cb19b3a1f,
|
||||
0x0a14f33a5fe668a60ac884b4ca607ad0f8abb5af40f96f1d7d543db52b003dcd,
|
||||
0x28ead9c586513eab1a5e86509d68b2da27be3a4f01171a1dd847df829bc683b9,
|
||||
0x1c6ab1c328c3c6430972031f1bdb2ac9888f0ea1abe71cffea16cda6e1a7416c,
|
||||
0x1fc7e71bc0b819792b2500239f7f8de04f6decd608cb98a932346015c5b42c94,
|
||||
0x03e107eb3a42b2ece380e0d860298f17c0c1e197c952650ee6dd85b93a0ddaa8,
|
||||
0x2d354a251f381a4669c0d52bf88b772c46452ca57c08697f454505f6941d78cd,
|
||||
0x094af88ab05d94baf687ef14bc566d1c522551d61606eda3d14b4606826f794b,
|
||||
0x19705b783bf3d2dc19bcaeabf02f8ca5e1ab5b6f2e3195a9d52b2d249d1396f7,
|
||||
0x09bf4acc3a8bce3f1fcc33fee54fc5b28723b16b7d740a3e60cef6852271200e,
|
||||
0x1803f8200db6013c50f83c0c8fab62843413732f301f7058543a073f3f3b5e4e,
|
||||
0x0f80afb5046244de30595b160b8d1f38bf6fb02d4454c0add41f7fef2faf3e5c,
|
||||
0x126ee1f8504f15c3d77f0088c1cfc964abcfcf643f4a6fea7dc3f98219529d78,
|
||||
0x23c203d10cfcc60f69bfb3d919552ca10ffb4ee63175ddf8ef86f991d7d0a591,
|
||||
0x2a2ae15d8b143709ec0d09705fa3a6303dec1ee4eec2cf747c5a339f7744fb94,
|
||||
0x07b60dee586ed6ef47e5c381ab6343ecc3d3b3006cb461bbb6b5d89081970b2b,
|
||||
0x27316b559be3edfd885d95c494c1ae3d8a98a320baa7d152132cfe583c9311bd,
|
||||
0x1d5c49ba157c32b8d8937cb2d3f84311ef834cc2a743ed662f5f9af0c0342e76,
|
||||
0x2f8b124e78163b2f332774e0b850b5ec09c01bf6979938f67c24bd5940968488,
|
||||
0x1e6843a5457416b6dc5b7aa09a9ce21b1d4cba6554e51d84665f75260113b3d5,
|
||||
0x11cdf00a35f650c55fca25c9929c8ad9a68daf9ac6a189ab1f5bc79f21641d4b,
|
||||
0x21632de3d3bbc5e42ef36e588158d6d4608b2815c77355b7e82b5b9b7eb560bc,
|
||||
0x0de625758452efbd97b27025fbd245e0255ae48ef2a329e449d7b5c51c18498a,
|
||||
0x2ad253c053e75213e2febfd4d976cc01dd9e1e1c6f0fb6b09b09546ba0838098,
|
||||
0x1d6b169ed63872dc6ec7681ec39b3be93dd49cdd13c813b7d35702e38d60b077,
|
||||
0x1660b740a143664bb9127c4941b67fed0be3ea70a24d5568c3a54e706cfef7fe,
|
||||
0x0065a92d1de81f34114f4ca2deef76e0ceacdddb12cf879096a29f10376ccbfe,
|
||||
0x1f11f065202535987367f823da7d672c353ebe2ccbc4869bcf30d50a5871040d,
|
||||
0x26596f5c5dd5a5d1b437ce7b14a2c3dd3bd1d1a39b6759ba110852d17df0693e,
|
||||
0x16f49bc727e45a2f7bf3056efcf8b6d38539c4163a5f1e706743db15af91860f,
|
||||
0x1abe1deb45b3e3119954175efb331bf4568feaf7ea8b3dc5e1a4e7438dd39e5f,
|
||||
0x0e426ccab66984d1d8993a74ca548b779f5db92aaec5f102020d34aea15fba59,
|
||||
0x0e7c30c2e2e8957f4933bd1942053f1f0071684b902d534fa841924303f6a6c6,
|
||||
0x0812a017ca92cf0a1622708fc7edff1d6166ded6e3528ead4c76e1f31d3fc69d,
|
||||
0x21a5ade3df2bc1b5bba949d1db96040068afe5026edd7a9c2e276b47cf010d54,
|
||||
0x01f3035463816c84ad711bf1a058c6c6bd101945f50e5afe72b1a5233f8749ce,
|
||||
0x0b115572f038c0e2028c2aafc2d06a5e8bf2f9398dbd0fdf4dcaa82b0f0c1c8b,
|
||||
0x1c38ec0b99b62fd4f0ef255543f50d2e27fc24db42bc910a3460613b6ef59e2f,
|
||||
0x1c89c6d9666272e8425c3ff1f4ac737b2f5d314606a297d4b1d0b254d880c53e,
|
||||
0x03326e643580356bf6d44008ae4c042a21ad4880097a5eb38b71e2311bb88f8f,
|
||||
0x268076b0054fb73f67cee9ea0e51e3ad50f27a6434b5dceb5bdde2299910a4c9,
|
||||
]
|
||||
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [F(0x1d066a255517b7fd8bddd3a93f7804ef7f8fcde48bb4c37a59a09a1a97052816)
|
||||
, F(0x29daefb55f6f2dc6ac3f089cebcc6120b7c6fef31367b68eb7238547d32c1610)
|
||||
, F(0x1f2cb1624a78ee001ecbd88ad959d7012572d76f08ec5c4f9e8b7ad7b0b4e1d1)
|
||||
]
|
||||
, [ F(0x0aad2e79f15735f2bd77c0ed3d14aa27b11f092a53bbc6e1db0672ded84f31e5)
|
||||
, F(0x2252624f8617738cd6f661dd4094375f37028a98f1dece66091ccf1595b43f28)
|
||||
, F(0x1a24913a928b38485a65a84a291da1ff91c20626524b2b87d49f4f2c9018d735)
|
||||
]
|
||||
, [ F(0x22fc468f1759b74d7bfc427b5f11ebb10a41515ddff497b14fd6dae1508fc47a)
|
||||
, F(0x1059ca787f1f89ed9cd026e9c9ca107ae61956ff0b4121d5efd65515617f6e4d)
|
||||
, F(0x02be9473358461d8f61f3536d877de982123011f0bf6f155a45cbbfae8b981ce)
|
||||
]
|
||||
, [ F(0x0ec96c8e32962d462778a749c82ed623aba9b669ac5b8736a1ff3a441a5084a4)
|
||||
, F(0x292f906e073677405442d9553c45fa3f5a47a7cdb8c99f9648fb2e4d814df57e)
|
||||
, F(0x274982444157b86726c11b9a0f5e39a5cc611160a394ea460c63f0b2ffe5657e)
|
||||
]
|
||||
, [ F(0x1acd63c67fbc9ab1626ed93491bda32e5da18ea9d8e4f10178d04aa6f8747ad0)
|
||||
, F(0x19f8a5d670e8ab66c4e3144be58ef6901bf93375e2323ec3ca8c86cd2a28b5a5)
|
||||
, F(0x1c0dc443519ad7a86efa40d2df10a011068193ea51f6c92ae1cfbb5f7b9b6893)
|
||||
]
|
||||
, [ F(0x14b39e7aa4068dbe50fe7190e421dc19fbeab33cb4f6a2c4180e4c3224987d3d)
|
||||
, F(0x1d449b71bd826ec58f28c63ea6c561b7b820fc519f01f021afb1e35e28b0795e)
|
||||
, F(0x1ea2c9a89baaddbb60fa97fe60fe9d8e89de141689d1252276524dc0a9e987fc)
|
||||
]
|
||||
, [ F(0x0478d66d43535a8cb57e9c1c3d6a2bd7591f9a46a0e9c058134d5cefdb3c7ff1)
|
||||
, F(0x19272db71eece6a6f608f3b2717f9cd2662e26ad86c400b21cde5e4a7b00bebe)
|
||||
, F(0x14226537335cab33c749c746f09208abb2dd1bd66a87ef75039be846af134166)
|
||||
]
|
||||
, [ F(0x01fd6af15956294f9dfe38c0d976a088b21c21e4a1c2e823f912f44961f9a9ce)
|
||||
, F(0x18e5abedd626ec307bca190b8b2cab1aaee2e62ed229ba5a5ad8518d4e5f2a57)
|
||||
, F(0x0fc1bbceba0590f5abbdffa6d3b35e3297c021a3a409926d0e2d54dc1c84fda6)
|
||||
]]
|
||||
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(0)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
# ———————————————————————
|
||||
# Main
|
||||
# ———————————————————————
|
||||
if len(sys.argv) != 5:
|
||||
print("Usage: python3 generate_inputs_for_poq.py <session> <core_quota> <leader_quota> <core (0) or leader (1)>")
|
||||
sys.exit(1)
|
||||
|
||||
session = int(sys.argv[1])
|
||||
Qc = int(sys.argv[2])
|
||||
Ql = int(sys.argv[3])
|
||||
core_or_leader = int(sys.argv[4])
|
||||
if not core_or_leader in [0,1]:
|
||||
print("core or leader must be 0 or 1")
|
||||
sys.exit(1)
|
||||
|
||||
# 1) Core‐node registry Merkle‐proof
|
||||
# pick a random core_sk and derive its public key
|
||||
core_sk = F(randrange(0,p,1))
|
||||
pk_core = poseidon2_hash([ F(1296193216988918402894), core_sk ])
|
||||
core_selectors = randrange(0,2**20,1)
|
||||
core_selectors = format(int(core_selectors),'020b')
|
||||
core_nodes = [F(randrange(0,p,1)) for i in range(20)]
|
||||
core_root = pk_core
|
||||
for i in range(20):
|
||||
if int(core_selectors[19-i]) == 0:
|
||||
core_root = poseidon2_hash([core_root,core_nodes[i]])
|
||||
else:
|
||||
core_root = poseidon2_hash([core_nodes[i],core_root])
|
||||
|
||||
#pk_root, core_path, core_selectors = merkle_root_and_path(pk_core, 20)
|
||||
|
||||
# 2) PoL inputs (broadened from pol script)
|
||||
epoch_nonce = F(randrange(0, p,1))
|
||||
slot_number = F(randrange(0, 2**32,1))
|
||||
total_stake = int(5000)
|
||||
|
||||
t0_constant = F(0x1a3fb997fd58374772808c13d1c2ddacb5ab3ea77413f86fd6e0d3d978e5438)
|
||||
t1_constant = F(0x71e790b41991052e30c93934b5612412e7958837bac8b1c524c24d84cc7d0)
|
||||
|
||||
t0 = F(int(t0_constant) // total_stake)
|
||||
t1 = F(p- (int(t1_constant) // total_stake**2))
|
||||
|
||||
value = F(total_stake / 100)
|
||||
threshold = (t0 + t1 * value) * value
|
||||
starting_slot = randrange(max(0,slot_number-2**25+1),slot_number,1)
|
||||
|
||||
slot_secret = F(randrange(0,p,1))
|
||||
slot_secret_indexes = format(int(slot_number - starting_slot),'025b')
|
||||
|
||||
tx_hash = F(randrange(0,p,1))
|
||||
output_number = F(randrange(0,50,1))
|
||||
|
||||
|
||||
slot_secret_path = [F(randrange(0,p,1)) for i in range(25)]
|
||||
secret_root = slot_secret
|
||||
for i in range(25):
|
||||
if int(slot_secret_indexes[24-i]) == 0:
|
||||
secret_root = poseidon2_hash([secret_root,slot_secret_path[i]])
|
||||
else:
|
||||
secret_root = poseidon2_hash([slot_secret_path[i],secret_root])
|
||||
sk = poseidon2_hash([F(256174383281726064679014503048630094),starting_slot,secret_root])
|
||||
pk = poseidon2_hash([F(1296193216988918402894),sk])
|
||||
|
||||
note_id = poseidon2_hash([F(65580641562429851895355409762135920462),tx_hash,output_number,value,pk])
|
||||
ticket = poseidon2_hash([F(13887241025832268),F(epoch_nonce),F(slot_number),note_id,sk])
|
||||
while(ticket > threshold):
|
||||
output_number += 1
|
||||
note_id = poseidon2_hash([F(65580641562429851895355409762135920462),tx_hash,output_number,value,pk])
|
||||
ticket = poseidon2_hash([F(13887241025832268),F(epoch_nonce),F(slot_number),note_id,sk])
|
||||
|
||||
aged_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
aged_selectors = randrange(0,2**32,1)
|
||||
aged_selectors = format(aged_selectors,'032b')
|
||||
aged_root = note_id
|
||||
for i in range(32):
|
||||
if int(aged_selectors[31-i]) == 0:
|
||||
aged_root = poseidon2_hash([aged_root,aged_nodes[i]])
|
||||
else:
|
||||
aged_root = poseidon2_hash([aged_nodes[i],aged_root])
|
||||
|
||||
# 3) Choose branch & index
|
||||
index = randrange(0, Ql if core_or_leader else Qc,1)
|
||||
|
||||
# 4) One‐time key
|
||||
K_one = F(123456)
|
||||
K_two = F(654321)
|
||||
|
||||
# 5) Assemble JSON
|
||||
inp = {
|
||||
"session": str(session),
|
||||
"core_quota": str(Qc),
|
||||
"leader_quota": str(Ql),
|
||||
"core_root": str(core_root),
|
||||
"pol_ledger_aged": str(aged_root),
|
||||
"K_part_one": str(K_one),
|
||||
"K_part_two": str(K_two),
|
||||
"selector": str(core_or_leader),
|
||||
"index": str(index),
|
||||
"core_sk": str(core_sk),
|
||||
"core_path": [str(x) for x in core_nodes],
|
||||
"core_path_selectors": [str(x) for x in core_selectors],
|
||||
"pol_sl": str(slot_number),
|
||||
"pol_epoch_nonce": str(epoch_nonce),
|
||||
"pol_t0": str(t0),
|
||||
"pol_t1": str(t1),
|
||||
"pol_slot_secret": str(slot_secret),
|
||||
"pol_slot_secret_path": [str(x) for x in slot_secret_path],
|
||||
"pol_noteid_path": [str(x) for x in aged_nodes],
|
||||
"pol_noteid_path_selectors": [str(x) for x in aged_selectors],
|
||||
"pol_note_tx_hash": str(tx_hash),
|
||||
"pol_note_output_number": str(output_number),
|
||||
"pol_sk_starting_slot": str(starting_slot),
|
||||
"pol_note_value": str(value)
|
||||
}
|
||||
|
||||
if core_or_leader == 0:
|
||||
inp["pol_ledger_aged"] = str(randrange(0,p,1))
|
||||
else:
|
||||
inp["core_root"] = str(randrange(0,p,1))
|
||||
|
||||
import json
|
||||
|
||||
with open("input.json","w") as f:
|
||||
json.dump(inp, f, indent=2)
|
||||
|
||||
print("Wrote input_poq.json")
|
||||
137
blend/poq.circom
Normal file
137
blend/poq.circom
Normal file
@ -0,0 +1,137 @@
|
||||
// PoQ.circom
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../hash_bn/poseidon2_hash.circom";
|
||||
include "../misc/constants.circom"; // defines NOMOS_KDF, SELECTION_RANDOMNESS, PROOF_NULLIFIER
|
||||
include "../misc/comparator.circom";
|
||||
include "../circomlib/circuits/bitify.circom";
|
||||
include "../Mantle/pol_lib.circom"; // defines proof_of_leadership
|
||||
include "../ledger/notes.circom";
|
||||
|
||||
/**
|
||||
* ProofOfQuota(nLevelsPK, nLevelsPol)
|
||||
*
|
||||
* - nLevelsPK : depth of the core-node public-key registry Merkle tree
|
||||
* - nLevelsPol : depth of the slot-secret tree used in PoL (25)
|
||||
* - bitsQuota : bit-width for the index comparator
|
||||
*/
|
||||
template ProofOfQuota(nLevelsPK, nLevelsPol, bitsQuota) {
|
||||
// Public Inputs
|
||||
signal input session; // session s
|
||||
signal input core_quota;
|
||||
signal input leader_quota;
|
||||
signal input core_root;
|
||||
signal input pol_ledger_aged; // PoL: aged notes root
|
||||
signal input K_part_one; // Blend: one-time signature public key
|
||||
signal input K_part_two; // Blend: one-time signature public key
|
||||
|
||||
|
||||
// dummy constraints to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy_one;
|
||||
dummy_one <== K_part_one * K_part_one;
|
||||
signal dummy_two;
|
||||
dummy_two <== K_part_two * K_part_two;
|
||||
|
||||
signal output key_nullifier; //key_nullifier
|
||||
|
||||
// Private Inputs
|
||||
signal input selector; // 0 = core, 1 = leader
|
||||
signal input index; // nullifier index
|
||||
|
||||
// Core-nodes inputs
|
||||
signal input core_sk; // core node secret key
|
||||
signal input core_path[nLevelsPK]; // Merkle path for core PK
|
||||
signal input core_path_selectors[nLevelsPK]; // path selectors (bits)
|
||||
|
||||
// PoL branch inputs (all the PoL private data)
|
||||
signal input pol_sl;
|
||||
signal input pol_epoch_nonce;
|
||||
signal input pol_t0;
|
||||
signal input pol_t1;
|
||||
signal input pol_slot_secret;
|
||||
signal input pol_slot_secret_path[nLevelsPol];
|
||||
|
||||
signal input pol_noteid_path[32];
|
||||
signal input pol_noteid_path_selectors[32];
|
||||
signal input pol_note_tx_hash;
|
||||
signal input pol_note_output_number;
|
||||
|
||||
signal input pol_sk_starting_slot;
|
||||
signal input pol_note_value;
|
||||
|
||||
|
||||
// Constraint the selector to be a bit
|
||||
selector * (1 - selector) === 0;
|
||||
|
||||
|
||||
// Quota check: index < core_quota if core, index < leader_quota if leader
|
||||
component cmp = SafeLessThan(bitsQuota);
|
||||
cmp.in[0] <== index;
|
||||
cmp.in[1] <== selector * (leader_quota - core_quota) + core_quota;
|
||||
cmp.out === 1;
|
||||
|
||||
|
||||
// derive zk_id
|
||||
component zk_id = derive_public_key();
|
||||
zk_id.secret_key <== core_sk;
|
||||
|
||||
|
||||
// Merkle‐verify zk_id in core_root
|
||||
component is_registered = proof_of_membership(nLevelsPK);
|
||||
for (var i = 0; i < nLevelsPK; i++) {
|
||||
//check that the selectors are indeed bits
|
||||
core_path_selectors[i] * (1 - core_path_selectors[i]) === 0;
|
||||
//call the merkle proof checker
|
||||
is_registered.nodes[i] <== core_path[i];
|
||||
is_registered.selector[i] <== core_path_selectors[i];
|
||||
}
|
||||
is_registered.root <== core_root;
|
||||
is_registered.leaf <== zk_id.out;
|
||||
|
||||
|
||||
// enforce potential PoL (without verification that the note is unspent)
|
||||
// (All constraints inside pol ensure LeadershipVerify)
|
||||
component would_win = would_win_leadership(nLevelsPol);
|
||||
would_win.slot <== pol_sl;
|
||||
would_win.epoch_nonce <== pol_epoch_nonce;
|
||||
would_win.t0 <== pol_t0;
|
||||
would_win.t1 <== pol_t1;
|
||||
would_win.slot_secret <== pol_slot_secret;
|
||||
for (var i = 0; i < nLevelsPol; i++) {
|
||||
would_win.slot_secret_path[i] <== pol_slot_secret_path[i];
|
||||
}
|
||||
for (var i = 0; i < 32; i++) {
|
||||
would_win.aged_nodes[i] <== pol_noteid_path[i];
|
||||
would_win.aged_selectors[i] <== pol_noteid_path_selectors[i];
|
||||
}
|
||||
would_win.aged_root <== pol_ledger_aged;
|
||||
would_win.transaction_hash <== pol_note_tx_hash;
|
||||
would_win.output_number <== pol_note_output_number;
|
||||
would_win.starting_slot <== pol_sk_starting_slot;
|
||||
would_win.value <== pol_note_value;
|
||||
|
||||
// Enforce the selected role is correct
|
||||
selector * (would_win.out - is_registered.out) + is_registered.out === 1;
|
||||
|
||||
|
||||
// Derive selection_randomness
|
||||
component selection_randomness = Poseidon2_hash(4);
|
||||
component dstSel = SELECTION_RANDOMNESS_V1();
|
||||
selection_randomness.inp[0] <== dstSel.out;
|
||||
// choose core_sk or pol.secret_key:
|
||||
selection_randomness.inp[1] <== selector * (would_win.secret_key - core_sk ) + core_sk;
|
||||
selection_randomness.inp[2] <== index;
|
||||
selection_randomness.inp[3] <== session;
|
||||
|
||||
|
||||
// Derive key_nullifier
|
||||
component nf = Poseidon2_hash(2);
|
||||
component dstNF = KEY_NULLIFIER_V1();
|
||||
nf.inp[0] <== dstNF.out;
|
||||
nf.inp[1] <== selection_randomness.out;
|
||||
key_nullifier <== nf.out;
|
||||
}
|
||||
|
||||
// Instantiate with chosen depths: 20 for core PK tree, 25 for PoL secret slot tree
|
||||
component main { public [ session, core_quota, leader_quota, core_root, K_part_one, K_part_two, pol_epoch_nonce, pol_t0, pol_t1, pol_ledger_aged ] }
|
||||
= ProofOfQuota(20, 25, 20);
|
||||
55
hash_bn/merkle.circom
Normal file
55
hash_bn/merkle.circom
Normal file
@ -0,0 +1,55 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../hash_bn/poseidon2_hash.circom";
|
||||
include "../circomlib/circuits/comparators.circom";
|
||||
|
||||
// compute a merkle root of depth n
|
||||
// /!\ To call this function, it's important to check that each selector is a bit before!!!
|
||||
template compute_merkle_root(n) {
|
||||
signal input nodes[n]; // The Merkle path
|
||||
signal input selector[n]; // it's the leaf's indice in big endian bits indicating if complementary nodes are left or right
|
||||
signal input leaf;
|
||||
signal output root;
|
||||
|
||||
|
||||
component compression_hash[n];
|
||||
|
||||
compression_hash[0] = Poseidon2_hash(2);
|
||||
compression_hash[0].inp[0] <== leaf - selector[n-1] * (leaf - nodes[0]);
|
||||
compression_hash[0].inp[1] <== nodes[0] - selector[n-1] * (nodes[0] - leaf);
|
||||
|
||||
for(var i=1; i<n; i++){
|
||||
compression_hash[i] = Poseidon2_hash(2);
|
||||
compression_hash[i].inp[0] <== compression_hash[i-1].out - selector[n-1-i] * (compression_hash[i-1].out - nodes[i]);
|
||||
compression_hash[i].inp[1] <== nodes[i] - selector[n-1-i] * (nodes[i] - compression_hash[i-1].out);
|
||||
}
|
||||
|
||||
root <== compression_hash[n-1].out;
|
||||
}
|
||||
|
||||
|
||||
// Verify a Merkle proof of depth n
|
||||
// /!\ To call this function, it's important to check that each selector is a bit before!!!
|
||||
template proof_of_membership(n) {
|
||||
signal input nodes[n]; // The Merkle path
|
||||
signal input selector[n]; // it's the leaf's indice in big endian bits indicating if complementary nodes are left or right
|
||||
signal input root;
|
||||
signal input leaf;
|
||||
signal output out;
|
||||
|
||||
|
||||
component root_calculator = compute_merkle_root(n);
|
||||
for(var i=0; i<n; i++){
|
||||
root_calculator.nodes[i] <== nodes[i];
|
||||
root_calculator.selector[i] <== selector[i];
|
||||
}
|
||||
root_calculator.leaf <== leaf;
|
||||
|
||||
|
||||
component eq = IsEqual();
|
||||
eq.in[0] <== root_calculator.root;
|
||||
eq.in[1] <== root;
|
||||
|
||||
out <== eq.out;
|
||||
}
|
||||
19
hash_bn/poseidon2_hash.circom
Normal file
19
hash_bn/poseidon2_hash.circom
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon2_sponge.circom";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Hash `n` field elements into 1, with approximately 254 bits of preimage security (?)
|
||||
// (assuming bn128 scalar field. We use capacity=2, rate=1, t=3).
|
||||
|
||||
template Poseidon2_hash(n) {
|
||||
signal input inp[n];
|
||||
signal output out;
|
||||
|
||||
component sponge = PoseidonSponge(3,2,n,1);
|
||||
sponge.inp <== inp;
|
||||
sponge.out[0] ==> out;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
217
hash_bn/poseidon2_perm.circom
Normal file
217
hash_bn/poseidon2_perm.circom
Normal file
@ -0,0 +1,217 @@
|
||||
//
|
||||
pragma circom 2.1.9;
|
||||
|
||||
//
|
||||
// The Poseidon2 permutation for bn128 and t=3
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// The S-box
|
||||
|
||||
template SBox() {
|
||||
signal input inp;
|
||||
signal output out;
|
||||
|
||||
signal x2 <== inp*inp;
|
||||
signal x4 <== x2*x2;
|
||||
|
||||
out <== inp*x4;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// partial or internal round
|
||||
|
||||
template InternalRound(i) {
|
||||
signal input inp[3];
|
||||
signal output out[3];
|
||||
|
||||
var round_consts[56] =
|
||||
[0x1a1d063e54b1e764b63e1855bff015b8cedd192f47308731499573f23597d4b5,
|
||||
0x26abc66f3fdf8e68839d10956259063708235dccc1aa3793b91b002c5b257c37,
|
||||
0x0c7c64a9d887385381a578cfed5aed370754427aabca92a70b3c2b12ff4d7be8,
|
||||
0x1cf5998769e9fab79e17f0b6d08b2d1eba2ebac30dc386b0edd383831354b495,
|
||||
0x0f5e3a8566be31b7564ca60461e9e08b19828764a9669bc17aba0b97e66b0109,
|
||||
0x18df6a9d19ea90d895e60e4db0794a01f359a53a180b7d4b42bf3d7a531c976e,
|
||||
0x04f7bf2c5c0538ac6e4b782c3c6e601ad0ea1d3a3b9d25ef4e324055fa3123dc,
|
||||
0x29c76ce22255206e3c40058523748531e770c0584aa2328ce55d54628b89ebe6,
|
||||
0x198d425a45b78e85c053659ab4347f5d65b1b8e9c6108dbe00e0e945dbc5ff15,
|
||||
0x25ee27ab6296cd5e6af3cc79c598a1daa7ff7f6878b3c49d49d3a9a90c3fdf74,
|
||||
0x138ea8e0af41a1e024561001c0b6eb1505845d7d0c55b1b2c0f88687a96d1381,
|
||||
0x306197fb3fab671ef6e7c2cba2eefd0e42851b5b9811f2ca4013370a01d95687,
|
||||
0x1a0c7d52dc32a4432b66f0b4894d4f1a21db7565e5b4250486419eaf00e8f620,
|
||||
0x2b46b418de80915f3ff86a8e5c8bdfccebfbe5f55163cd6caa52997da2c54a9f,
|
||||
0x12d3e0dc0085873701f8b777b9673af9613a1af5db48e05bfb46e312b5829f64,
|
||||
0x263390cf74dc3a8870f5002ed21d089ffb2bf768230f648dba338a5cb19b3a1f,
|
||||
0x0a14f33a5fe668a60ac884b4ca607ad0f8abb5af40f96f1d7d543db52b003dcd,
|
||||
0x28ead9c586513eab1a5e86509d68b2da27be3a4f01171a1dd847df829bc683b9,
|
||||
0x1c6ab1c328c3c6430972031f1bdb2ac9888f0ea1abe71cffea16cda6e1a7416c,
|
||||
0x1fc7e71bc0b819792b2500239f7f8de04f6decd608cb98a932346015c5b42c94,
|
||||
0x03e107eb3a42b2ece380e0d860298f17c0c1e197c952650ee6dd85b93a0ddaa8,
|
||||
0x2d354a251f381a4669c0d52bf88b772c46452ca57c08697f454505f6941d78cd,
|
||||
0x094af88ab05d94baf687ef14bc566d1c522551d61606eda3d14b4606826f794b,
|
||||
0x19705b783bf3d2dc19bcaeabf02f8ca5e1ab5b6f2e3195a9d52b2d249d1396f7,
|
||||
0x09bf4acc3a8bce3f1fcc33fee54fc5b28723b16b7d740a3e60cef6852271200e,
|
||||
0x1803f8200db6013c50f83c0c8fab62843413732f301f7058543a073f3f3b5e4e,
|
||||
0x0f80afb5046244de30595b160b8d1f38bf6fb02d4454c0add41f7fef2faf3e5c,
|
||||
0x126ee1f8504f15c3d77f0088c1cfc964abcfcf643f4a6fea7dc3f98219529d78,
|
||||
0x23c203d10cfcc60f69bfb3d919552ca10ffb4ee63175ddf8ef86f991d7d0a591,
|
||||
0x2a2ae15d8b143709ec0d09705fa3a6303dec1ee4eec2cf747c5a339f7744fb94,
|
||||
0x07b60dee586ed6ef47e5c381ab6343ecc3d3b3006cb461bbb6b5d89081970b2b,
|
||||
0x27316b559be3edfd885d95c494c1ae3d8a98a320baa7d152132cfe583c9311bd,
|
||||
0x1d5c49ba157c32b8d8937cb2d3f84311ef834cc2a743ed662f5f9af0c0342e76,
|
||||
0x2f8b124e78163b2f332774e0b850b5ec09c01bf6979938f67c24bd5940968488,
|
||||
0x1e6843a5457416b6dc5b7aa09a9ce21b1d4cba6554e51d84665f75260113b3d5,
|
||||
0x11cdf00a35f650c55fca25c9929c8ad9a68daf9ac6a189ab1f5bc79f21641d4b,
|
||||
0x21632de3d3bbc5e42ef36e588158d6d4608b2815c77355b7e82b5b9b7eb560bc,
|
||||
0x0de625758452efbd97b27025fbd245e0255ae48ef2a329e449d7b5c51c18498a,
|
||||
0x2ad253c053e75213e2febfd4d976cc01dd9e1e1c6f0fb6b09b09546ba0838098,
|
||||
0x1d6b169ed63872dc6ec7681ec39b3be93dd49cdd13c813b7d35702e38d60b077,
|
||||
0x1660b740a143664bb9127c4941b67fed0be3ea70a24d5568c3a54e706cfef7fe,
|
||||
0x0065a92d1de81f34114f4ca2deef76e0ceacdddb12cf879096a29f10376ccbfe,
|
||||
0x1f11f065202535987367f823da7d672c353ebe2ccbc4869bcf30d50a5871040d,
|
||||
0x26596f5c5dd5a5d1b437ce7b14a2c3dd3bd1d1a39b6759ba110852d17df0693e,
|
||||
0x16f49bc727e45a2f7bf3056efcf8b6d38539c4163a5f1e706743db15af91860f,
|
||||
0x1abe1deb45b3e3119954175efb331bf4568feaf7ea8b3dc5e1a4e7438dd39e5f,
|
||||
0x0e426ccab66984d1d8993a74ca548b779f5db92aaec5f102020d34aea15fba59,
|
||||
0x0e7c30c2e2e8957f4933bd1942053f1f0071684b902d534fa841924303f6a6c6,
|
||||
0x0812a017ca92cf0a1622708fc7edff1d6166ded6e3528ead4c76e1f31d3fc69d,
|
||||
0x21a5ade3df2bc1b5bba949d1db96040068afe5026edd7a9c2e276b47cf010d54,
|
||||
0x01f3035463816c84ad711bf1a058c6c6bd101945f50e5afe72b1a5233f8749ce,
|
||||
0x0b115572f038c0e2028c2aafc2d06a5e8bf2f9398dbd0fdf4dcaa82b0f0c1c8b,
|
||||
0x1c38ec0b99b62fd4f0ef255543f50d2e27fc24db42bc910a3460613b6ef59e2f,
|
||||
0x1c89c6d9666272e8425c3ff1f4ac737b2f5d314606a297d4b1d0b254d880c53e,
|
||||
0x03326e643580356bf6d44008ae4c042a21ad4880097a5eb38b71e2311bb88f8f,
|
||||
0x268076b0054fb73f67cee9ea0e51e3ad50f27a6434b5dceb5bdde2299910a4c9];
|
||||
|
||||
component sb = SBox();
|
||||
sb.inp <== inp[0] + round_consts[i];
|
||||
|
||||
out[0] <== 2*sb.out + inp[1] + inp[2];
|
||||
out[1] <== sb.out + 2*inp[1] + inp[2];
|
||||
out[2] <== sb.out + inp[1] + 3*inp[2];
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// external rounds
|
||||
|
||||
template ExternalRound(i) {
|
||||
signal input inp[3];
|
||||
signal output out[3];
|
||||
|
||||
var round_consts[8][3] =
|
||||
|
||||
[ [ 0x1d066a255517b7fd8bddd3a93f7804ef7f8fcde48bb4c37a59a09a1a97052816
|
||||
, 0x29daefb55f6f2dc6ac3f089cebcc6120b7c6fef31367b68eb7238547d32c1610
|
||||
, 0x1f2cb1624a78ee001ecbd88ad959d7012572d76f08ec5c4f9e8b7ad7b0b4e1d1
|
||||
]
|
||||
, [ 0x0aad2e79f15735f2bd77c0ed3d14aa27b11f092a53bbc6e1db0672ded84f31e5
|
||||
, 0x2252624f8617738cd6f661dd4094375f37028a98f1dece66091ccf1595b43f28
|
||||
, 0x1a24913a928b38485a65a84a291da1ff91c20626524b2b87d49f4f2c9018d735
|
||||
]
|
||||
, [ 0x22fc468f1759b74d7bfc427b5f11ebb10a41515ddff497b14fd6dae1508fc47a
|
||||
, 0x1059ca787f1f89ed9cd026e9c9ca107ae61956ff0b4121d5efd65515617f6e4d
|
||||
, 0x02be9473358461d8f61f3536d877de982123011f0bf6f155a45cbbfae8b981ce
|
||||
]
|
||||
, [ 0x0ec96c8e32962d462778a749c82ed623aba9b669ac5b8736a1ff3a441a5084a4
|
||||
, 0x292f906e073677405442d9553c45fa3f5a47a7cdb8c99f9648fb2e4d814df57e
|
||||
, 0x274982444157b86726c11b9a0f5e39a5cc611160a394ea460c63f0b2ffe5657e
|
||||
]
|
||||
, [ 0x1acd63c67fbc9ab1626ed93491bda32e5da18ea9d8e4f10178d04aa6f8747ad0
|
||||
, 0x19f8a5d670e8ab66c4e3144be58ef6901bf93375e2323ec3ca8c86cd2a28b5a5
|
||||
, 0x1c0dc443519ad7a86efa40d2df10a011068193ea51f6c92ae1cfbb5f7b9b6893
|
||||
]
|
||||
, [ 0x14b39e7aa4068dbe50fe7190e421dc19fbeab33cb4f6a2c4180e4c3224987d3d
|
||||
, 0x1d449b71bd826ec58f28c63ea6c561b7b820fc519f01f021afb1e35e28b0795e
|
||||
, 0x1ea2c9a89baaddbb60fa97fe60fe9d8e89de141689d1252276524dc0a9e987fc
|
||||
]
|
||||
, [ 0x0478d66d43535a8cb57e9c1c3d6a2bd7591f9a46a0e9c058134d5cefdb3c7ff1
|
||||
, 0x19272db71eece6a6f608f3b2717f9cd2662e26ad86c400b21cde5e4a7b00bebe
|
||||
, 0x14226537335cab33c749c746f09208abb2dd1bd66a87ef75039be846af134166
|
||||
]
|
||||
, [ 0x01fd6af15956294f9dfe38c0d976a088b21c21e4a1c2e823f912f44961f9a9ce
|
||||
, 0x18e5abedd626ec307bca190b8b2cab1aaee2e62ed229ba5a5ad8518d4e5f2a57
|
||||
, 0x0fc1bbceba0590f5abbdffa6d3b35e3297c021a3a409926d0e2d54dc1c84fda6
|
||||
]
|
||||
];
|
||||
|
||||
component sb[3];
|
||||
for(var j=0; j<3; j++) {
|
||||
sb[j] = SBox();
|
||||
sb[j].inp <== inp[j] + round_consts[i][j];
|
||||
}
|
||||
|
||||
out[0] <== 2*sb[0].out + sb[1].out + sb[2].out;
|
||||
out[1] <== sb[0].out + 2*sb[1].out + sb[2].out;
|
||||
out[2] <== sb[0].out + sb[1].out + 2*sb[2].out;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// the initial linear layer
|
||||
|
||||
template LinearLayer() {
|
||||
signal input inp[3];
|
||||
signal output out[3];
|
||||
out[0] <== 2*inp[0] + inp[1] + inp[2];
|
||||
out[1] <== inp[0] + 2*inp[1] + inp[2];
|
||||
out[2] <== inp[0] + inp[1] + 2*inp[2];
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// the Poseidon2 permutation for t=3
|
||||
|
||||
template Permutation() {
|
||||
signal input inp[3];
|
||||
signal output out[3];
|
||||
|
||||
signal aux[65][3];
|
||||
|
||||
component ll = LinearLayer();
|
||||
for(var j=0; j<3; j++) { ll.inp[j] <== inp[j]; }
|
||||
for(var j=0; j<3; j++) { ll.out[j] ==> aux[0][j]; }
|
||||
|
||||
component ext[8];
|
||||
for(var k=0; k<8; k++) { ext[k] = ExternalRound(k); }
|
||||
|
||||
component int[56];
|
||||
for(var k=0; k<56; k++) { int[k] = InternalRound(k); }
|
||||
|
||||
// first 4 external rounds
|
||||
for(var k=0; k<4; k++) {
|
||||
for(var j=0; j<3; j++) { ext[k].inp[j] <== aux[k ][j]; }
|
||||
for(var j=0; j<3; j++) { ext[k].out[j] ==> aux[k+1][j]; }
|
||||
}
|
||||
|
||||
// the 56 internal rounds
|
||||
for(var k=0; k<56; k++) {
|
||||
for(var j=0; j<3; j++) { int[k].inp[j] <== aux[k+4][j]; }
|
||||
for(var j=0; j<3; j++) { int[k].out[j] ==> aux[k+5][j]; }
|
||||
}
|
||||
|
||||
// last 4 external rounds
|
||||
for(var k=0; k<4; k++) {
|
||||
for(var j=0; j<3; j++) { ext[k+4].inp[j] <== aux[k+60][j]; }
|
||||
for(var j=0; j<3; j++) { ext[k+4].out[j] ==> aux[k+61][j]; }
|
||||
}
|
||||
|
||||
for(var j=0; j<3; j++) { out[j] <== aux[64][j]; }
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// the "compression function" takes 2 field elements as input and produces
|
||||
// 1 field element as output. It is a trivial application of the permutation.
|
||||
|
||||
template Compression() {
|
||||
signal input inp[2];
|
||||
signal output out;
|
||||
|
||||
component perm = Permutation();
|
||||
perm.inp[0] <== inp[0];
|
||||
perm.inp[1] <== inp[1];
|
||||
perm.inp[2] <== 0;
|
||||
|
||||
perm.out[0] ==> out;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
123
hash_bn/poseidon2_sponge.circom
Normal file
123
hash_bn/poseidon2_sponge.circom
Normal file
@ -0,0 +1,123 @@
|
||||
//
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon2_perm.circom";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
function min(a,b) {
|
||||
return (a <= b) ? a : b;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Poseidon sponge construction
|
||||
//
|
||||
// t = size of state (currently fixed to 3)
|
||||
// c = capacity (1 or 2)
|
||||
// r = rate = t - c
|
||||
//
|
||||
// everything is measured in number of field elements
|
||||
//
|
||||
// we use the padding `10*` from the original Poseidon paper,
|
||||
// and initial state constant zero. Note that this is different
|
||||
// from the "SAFE padding" recommended in the Poseidon2 paper
|
||||
// (which uses `0*` padding and a nontrivial initial state)
|
||||
//
|
||||
|
||||
template PoseidonSponge(t, capacity, input_len, output_len) {
|
||||
|
||||
var rate = t - capacity;
|
||||
|
||||
assert( t == 3);
|
||||
|
||||
assert( capacity > 0 );
|
||||
assert( rate > 0 );
|
||||
assert( capacity < t );
|
||||
assert( rate < t );
|
||||
|
||||
signal input inp[ input_len];
|
||||
signal output out[output_len];
|
||||
|
||||
// round up to rate the input + 1 field element ("10*" padding)
|
||||
var nblocks = ((input_len + 1) + (rate-1)) \ rate;
|
||||
var nout = (output_len + (rate-1)) \ rate;
|
||||
var padded_len = nblocks * rate;
|
||||
|
||||
signal padded[padded_len];
|
||||
for(var i=0; i<input_len; i++) { padded[i] <== inp[i]; }
|
||||
padded[input_len ] <== 1;
|
||||
for(var i=input_len+1; i<padded_len; i++) { padded[i] <== 0; }
|
||||
|
||||
signal state [nblocks+nout][t ];
|
||||
signal sorbed[nblocks ][rate];
|
||||
|
||||
// initialize state
|
||||
for(var i=0; i<t; i++) { state[0][i] <== 0; }
|
||||
|
||||
component absorb [nblocks];
|
||||
component squeeze[nout-1];
|
||||
|
||||
for(var m=0; m<nblocks; m++) {
|
||||
|
||||
for(var i=0; i<rate; i++) {
|
||||
var a = state [m][i];
|
||||
var b = padded[m*rate+i];
|
||||
sorbed[m][i] <== a + b;
|
||||
}
|
||||
|
||||
absorb[m] = Permutation();
|
||||
for(var j=0 ; j<rate; j++) { absorb[m].inp[j] <== sorbed[m][j]; }
|
||||
for(var j=rate; j<t ; j++) { absorb[m].inp[j] <== state [m][j]; }
|
||||
absorb[m].out ==> state[m+1];
|
||||
|
||||
}
|
||||
|
||||
var q = min(rate, output_len);
|
||||
for(var i=0; i<q; i++) {
|
||||
state[nblocks][i] ==> out[i];
|
||||
}
|
||||
var out_ptr = rate;
|
||||
|
||||
for(var n=1; n<nout; n++) {
|
||||
squeeze[n-1] = Permutation();
|
||||
squeeze[n-1].inp <== state[nblocks+n-1];
|
||||
squeeze[n-1].out ==> state[nblocks+n ];
|
||||
|
||||
var q = min(rate, output_len-out_ptr);
|
||||
for(var i=0; i<q; i++) {
|
||||
state[nblocks+n][i] ==> out[out_ptr+i];
|
||||
}
|
||||
out_ptr += rate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// sponge hash with rate=1
|
||||
//
|
||||
|
||||
template Poseidon2_sponge_hash_rate_1(n) {
|
||||
signal input inp[n];
|
||||
signal output out;
|
||||
component sponge = PoseidonSponge(3, 2, n, 1);
|
||||
sponge.inp <== inp;
|
||||
sponge.out[0] ==> out;
|
||||
}
|
||||
|
||||
//
|
||||
// sponge hash with rate=2
|
||||
//
|
||||
|
||||
template Poseidon2_sponge_hash_rate_2(n) {
|
||||
signal input inp[n];
|
||||
signal output out;
|
||||
component sponge = PoseidonSponge(3, 1, n, 1);
|
||||
sponge.inp <== inp;
|
||||
sponge.out[0] ==> out;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
30
ledger/notes.circom
Normal file
30
ledger/notes.circom
Normal file
@ -0,0 +1,30 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../hash_bn/poseidon2_hash.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template derive_secret_key(){
|
||||
signal input starting_slot;
|
||||
signal input secrets_root;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(3);
|
||||
component dst = NOMOS_POL_SK_V1();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== starting_slot;
|
||||
hash.inp[2] <== secrets_root;
|
||||
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
template derive_public_key(){
|
||||
signal input secret_key;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(2);
|
||||
component dst = NOMOS_KDF();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== secret_key;
|
||||
out <== hash.out;
|
||||
}
|
||||
308
mantle/generate_inputs_for_pol.py
Executable file
308
mantle/generate_inputs_for_pol.py
Executable file
@ -0,0 +1,308 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [
|
||||
0x1a1d063e54b1e764b63e1855bff015b8cedd192f47308731499573f23597d4b5,
|
||||
0x26abc66f3fdf8e68839d10956259063708235dccc1aa3793b91b002c5b257c37,
|
||||
0x0c7c64a9d887385381a578cfed5aed370754427aabca92a70b3c2b12ff4d7be8,
|
||||
0x1cf5998769e9fab79e17f0b6d08b2d1eba2ebac30dc386b0edd383831354b495,
|
||||
0x0f5e3a8566be31b7564ca60461e9e08b19828764a9669bc17aba0b97e66b0109,
|
||||
0x18df6a9d19ea90d895e60e4db0794a01f359a53a180b7d4b42bf3d7a531c976e,
|
||||
0x04f7bf2c5c0538ac6e4b782c3c6e601ad0ea1d3a3b9d25ef4e324055fa3123dc,
|
||||
0x29c76ce22255206e3c40058523748531e770c0584aa2328ce55d54628b89ebe6,
|
||||
0x198d425a45b78e85c053659ab4347f5d65b1b8e9c6108dbe00e0e945dbc5ff15,
|
||||
0x25ee27ab6296cd5e6af3cc79c598a1daa7ff7f6878b3c49d49d3a9a90c3fdf74,
|
||||
0x138ea8e0af41a1e024561001c0b6eb1505845d7d0c55b1b2c0f88687a96d1381,
|
||||
0x306197fb3fab671ef6e7c2cba2eefd0e42851b5b9811f2ca4013370a01d95687,
|
||||
0x1a0c7d52dc32a4432b66f0b4894d4f1a21db7565e5b4250486419eaf00e8f620,
|
||||
0x2b46b418de80915f3ff86a8e5c8bdfccebfbe5f55163cd6caa52997da2c54a9f,
|
||||
0x12d3e0dc0085873701f8b777b9673af9613a1af5db48e05bfb46e312b5829f64,
|
||||
0x263390cf74dc3a8870f5002ed21d089ffb2bf768230f648dba338a5cb19b3a1f,
|
||||
0x0a14f33a5fe668a60ac884b4ca607ad0f8abb5af40f96f1d7d543db52b003dcd,
|
||||
0x28ead9c586513eab1a5e86509d68b2da27be3a4f01171a1dd847df829bc683b9,
|
||||
0x1c6ab1c328c3c6430972031f1bdb2ac9888f0ea1abe71cffea16cda6e1a7416c,
|
||||
0x1fc7e71bc0b819792b2500239f7f8de04f6decd608cb98a932346015c5b42c94,
|
||||
0x03e107eb3a42b2ece380e0d860298f17c0c1e197c952650ee6dd85b93a0ddaa8,
|
||||
0x2d354a251f381a4669c0d52bf88b772c46452ca57c08697f454505f6941d78cd,
|
||||
0x094af88ab05d94baf687ef14bc566d1c522551d61606eda3d14b4606826f794b,
|
||||
0x19705b783bf3d2dc19bcaeabf02f8ca5e1ab5b6f2e3195a9d52b2d249d1396f7,
|
||||
0x09bf4acc3a8bce3f1fcc33fee54fc5b28723b16b7d740a3e60cef6852271200e,
|
||||
0x1803f8200db6013c50f83c0c8fab62843413732f301f7058543a073f3f3b5e4e,
|
||||
0x0f80afb5046244de30595b160b8d1f38bf6fb02d4454c0add41f7fef2faf3e5c,
|
||||
0x126ee1f8504f15c3d77f0088c1cfc964abcfcf643f4a6fea7dc3f98219529d78,
|
||||
0x23c203d10cfcc60f69bfb3d919552ca10ffb4ee63175ddf8ef86f991d7d0a591,
|
||||
0x2a2ae15d8b143709ec0d09705fa3a6303dec1ee4eec2cf747c5a339f7744fb94,
|
||||
0x07b60dee586ed6ef47e5c381ab6343ecc3d3b3006cb461bbb6b5d89081970b2b,
|
||||
0x27316b559be3edfd885d95c494c1ae3d8a98a320baa7d152132cfe583c9311bd,
|
||||
0x1d5c49ba157c32b8d8937cb2d3f84311ef834cc2a743ed662f5f9af0c0342e76,
|
||||
0x2f8b124e78163b2f332774e0b850b5ec09c01bf6979938f67c24bd5940968488,
|
||||
0x1e6843a5457416b6dc5b7aa09a9ce21b1d4cba6554e51d84665f75260113b3d5,
|
||||
0x11cdf00a35f650c55fca25c9929c8ad9a68daf9ac6a189ab1f5bc79f21641d4b,
|
||||
0x21632de3d3bbc5e42ef36e588158d6d4608b2815c77355b7e82b5b9b7eb560bc,
|
||||
0x0de625758452efbd97b27025fbd245e0255ae48ef2a329e449d7b5c51c18498a,
|
||||
0x2ad253c053e75213e2febfd4d976cc01dd9e1e1c6f0fb6b09b09546ba0838098,
|
||||
0x1d6b169ed63872dc6ec7681ec39b3be93dd49cdd13c813b7d35702e38d60b077,
|
||||
0x1660b740a143664bb9127c4941b67fed0be3ea70a24d5568c3a54e706cfef7fe,
|
||||
0x0065a92d1de81f34114f4ca2deef76e0ceacdddb12cf879096a29f10376ccbfe,
|
||||
0x1f11f065202535987367f823da7d672c353ebe2ccbc4869bcf30d50a5871040d,
|
||||
0x26596f5c5dd5a5d1b437ce7b14a2c3dd3bd1d1a39b6759ba110852d17df0693e,
|
||||
0x16f49bc727e45a2f7bf3056efcf8b6d38539c4163a5f1e706743db15af91860f,
|
||||
0x1abe1deb45b3e3119954175efb331bf4568feaf7ea8b3dc5e1a4e7438dd39e5f,
|
||||
0x0e426ccab66984d1d8993a74ca548b779f5db92aaec5f102020d34aea15fba59,
|
||||
0x0e7c30c2e2e8957f4933bd1942053f1f0071684b902d534fa841924303f6a6c6,
|
||||
0x0812a017ca92cf0a1622708fc7edff1d6166ded6e3528ead4c76e1f31d3fc69d,
|
||||
0x21a5ade3df2bc1b5bba949d1db96040068afe5026edd7a9c2e276b47cf010d54,
|
||||
0x01f3035463816c84ad711bf1a058c6c6bd101945f50e5afe72b1a5233f8749ce,
|
||||
0x0b115572f038c0e2028c2aafc2d06a5e8bf2f9398dbd0fdf4dcaa82b0f0c1c8b,
|
||||
0x1c38ec0b99b62fd4f0ef255543f50d2e27fc24db42bc910a3460613b6ef59e2f,
|
||||
0x1c89c6d9666272e8425c3ff1f4ac737b2f5d314606a297d4b1d0b254d880c53e,
|
||||
0x03326e643580356bf6d44008ae4c042a21ad4880097a5eb38b71e2311bb88f8f,
|
||||
0x268076b0054fb73f67cee9ea0e51e3ad50f27a6434b5dceb5bdde2299910a4c9,
|
||||
]
|
||||
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [F(0x1d066a255517b7fd8bddd3a93f7804ef7f8fcde48bb4c37a59a09a1a97052816)
|
||||
, F(0x29daefb55f6f2dc6ac3f089cebcc6120b7c6fef31367b68eb7238547d32c1610)
|
||||
, F(0x1f2cb1624a78ee001ecbd88ad959d7012572d76f08ec5c4f9e8b7ad7b0b4e1d1)
|
||||
]
|
||||
, [ F(0x0aad2e79f15735f2bd77c0ed3d14aa27b11f092a53bbc6e1db0672ded84f31e5)
|
||||
, F(0x2252624f8617738cd6f661dd4094375f37028a98f1dece66091ccf1595b43f28)
|
||||
, F(0x1a24913a928b38485a65a84a291da1ff91c20626524b2b87d49f4f2c9018d735)
|
||||
]
|
||||
, [ F(0x22fc468f1759b74d7bfc427b5f11ebb10a41515ddff497b14fd6dae1508fc47a)
|
||||
, F(0x1059ca787f1f89ed9cd026e9c9ca107ae61956ff0b4121d5efd65515617f6e4d)
|
||||
, F(0x02be9473358461d8f61f3536d877de982123011f0bf6f155a45cbbfae8b981ce)
|
||||
]
|
||||
, [ F(0x0ec96c8e32962d462778a749c82ed623aba9b669ac5b8736a1ff3a441a5084a4)
|
||||
, F(0x292f906e073677405442d9553c45fa3f5a47a7cdb8c99f9648fb2e4d814df57e)
|
||||
, F(0x274982444157b86726c11b9a0f5e39a5cc611160a394ea460c63f0b2ffe5657e)
|
||||
]
|
||||
, [ F(0x1acd63c67fbc9ab1626ed93491bda32e5da18ea9d8e4f10178d04aa6f8747ad0)
|
||||
, F(0x19f8a5d670e8ab66c4e3144be58ef6901bf93375e2323ec3ca8c86cd2a28b5a5)
|
||||
, F(0x1c0dc443519ad7a86efa40d2df10a011068193ea51f6c92ae1cfbb5f7b9b6893)
|
||||
]
|
||||
, [ F(0x14b39e7aa4068dbe50fe7190e421dc19fbeab33cb4f6a2c4180e4c3224987d3d)
|
||||
, F(0x1d449b71bd826ec58f28c63ea6c561b7b820fc519f01f021afb1e35e28b0795e)
|
||||
, F(0x1ea2c9a89baaddbb60fa97fe60fe9d8e89de141689d1252276524dc0a9e987fc)
|
||||
]
|
||||
, [ F(0x0478d66d43535a8cb57e9c1c3d6a2bd7591f9a46a0e9c058134d5cefdb3c7ff1)
|
||||
, F(0x19272db71eece6a6f608f3b2717f9cd2662e26ad86c400b21cde5e4a7b00bebe)
|
||||
, F(0x14226537335cab33c749c746f09208abb2dd1bd66a87ef75039be846af134166)
|
||||
]
|
||||
, [ F(0x01fd6af15956294f9dfe38c0d976a088b21c21e4a1c2e823f912f44961f9a9ce)
|
||||
, F(0x18e5abedd626ec307bca190b8b2cab1aaee2e62ed229ba5a5ad8518d4e5f2a57)
|
||||
, F(0x0fc1bbceba0590f5abbdffa6d3b35e3297c021a3a409926d0e2d54dc1c84fda6)
|
||||
]]
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(0)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
|
||||
if len(sys.argv) != Integer(4):
|
||||
print("Usage: <script> <epoch_nonce> <slot_number> <total_stake>")
|
||||
exit()
|
||||
|
||||
epoch_nonce = int(sys.argv[Integer(1)])
|
||||
slot_number = int(sys.argv[Integer(2)])
|
||||
total_stake = int(sys.argv[Integer(3)])
|
||||
|
||||
if epoch_nonce >= p:
|
||||
print("epoch nonce must be less than p")
|
||||
exit()
|
||||
if total_stake >= p:
|
||||
print("total stake must be less than p")
|
||||
exit()
|
||||
|
||||
t0_constant = F(0x1a3fb997fd58374772808c13d1c2ddacb5ab3ea77413f86fd6e0d3d978e5438)
|
||||
t1_constant = F(0x71e790b41991052e30c93934b5612412e7958837bac8b1c524c24d84cc7d0)
|
||||
|
||||
t0 = F(int(t0_constant) // total_stake)
|
||||
t1 = F(p- (int(t1_constant) // total_stake**2))
|
||||
|
||||
|
||||
value = F(total_stake / 100)
|
||||
threshold = (t0 + t1 * value) * value
|
||||
starting_slot = randrange(max(0,slot_number-2**25+1),slot_number,1)
|
||||
|
||||
slot_secret = F(randrange(0,p,1))
|
||||
slot_secret_indexes = format(int(slot_number - starting_slot),'025b')
|
||||
|
||||
tx_hash = F(randrange(0,p,1))
|
||||
output_number = F(randrange(0,50,1))
|
||||
|
||||
|
||||
slot_secret_path = [F(randrange(0,p,1)) for i in range(25)]
|
||||
secret_root = slot_secret
|
||||
for i in range(25):
|
||||
if int(slot_secret_indexes[24-i]) == 0:
|
||||
secret_root = poseidon2_hash([secret_root,slot_secret_path[i]])
|
||||
else:
|
||||
secret_root = poseidon2_hash([slot_secret_path[i],secret_root])
|
||||
sk = poseidon2_hash([F(256174383281726064679014503048630094),starting_slot,secret_root])
|
||||
pk = poseidon2_hash([F(1296193216988918402894),sk])
|
||||
|
||||
note_id = poseidon2_hash([F(65580641562429851895355409762135920462),tx_hash,output_number,value,pk])
|
||||
ticket = poseidon2_hash([F(13887241025832268),F(epoch_nonce),F(slot_number),note_id,sk])
|
||||
while(ticket > threshold):
|
||||
output_number += 1
|
||||
note_id = poseidon2_hash([F(65580641562429851895355409762135920462),tx_hash,output_number,value,pk])
|
||||
ticket = poseidon2_hash([F(13887241025832268),F(epoch_nonce),F(slot_number),note_id,sk])
|
||||
|
||||
aged_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
aged_selectors = randrange(0,2**32,1)
|
||||
aged_selectors = format(aged_selectors,'032b')
|
||||
aged_root = note_id
|
||||
for i in range(32):
|
||||
if int(aged_selectors[31-i]) == 0:
|
||||
aged_root = poseidon2_hash([aged_root,aged_nodes[i]])
|
||||
else:
|
||||
aged_root = poseidon2_hash([aged_nodes[i],aged_root])
|
||||
|
||||
unspent_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
unspent_selectors = randrange(0,2**32,1)
|
||||
unspent_selectors = format(unspent_selectors,'032b')
|
||||
|
||||
latest_root = note_id
|
||||
for i in range(32):
|
||||
if int(unspent_selectors[31-i]) == 0:
|
||||
latest_root = poseidon2_hash([latest_root,unspent_nodes[i]])
|
||||
else:
|
||||
latest_root = poseidon2_hash([unspent_nodes[i],latest_root])
|
||||
|
||||
|
||||
|
||||
|
||||
# 5) Assemble JSON
|
||||
inp = {
|
||||
"sl": str(slot_number),
|
||||
"epoch_nonce": str(epoch_nonce),
|
||||
"t0": str(t0),
|
||||
"t1": str(t1),
|
||||
"slot_secret": str(slot_secret),
|
||||
"P_lead_part_one": str(F(123456)),
|
||||
"P_lead_part_two": str(F(654321)),
|
||||
"slot_secret_path": [str(x) for x in slot_secret_path],
|
||||
"noteid_aged_path": [str(x) for x in aged_nodes],
|
||||
"noteid_aged_selectors": [str(x) for x in aged_selectors],
|
||||
"ledger_aged": str(aged_root),
|
||||
"note_tx_hash": str(tx_hash),
|
||||
"note_output_number": str(output_number),
|
||||
"noteid_latest_path": [str(x) for x in unspent_nodes],
|
||||
"noteid_latest_selectors": [str(x) for x in unspent_selectors],
|
||||
"ledger_latest": str(latest_root),
|
||||
"starting_slot": str(starting_slot),
|
||||
"v": str(value)
|
||||
}
|
||||
|
||||
import json
|
||||
|
||||
with open("input.json","w") as f:
|
||||
json.dump(inp, f, indent=2)
|
||||
|
||||
print("Wrote input of pol")
|
||||
238
mantle/generate_inputs_for_proof_of_claim.py
Executable file
238
mantle/generate_inputs_for_proof_of_claim.py
Executable file
@ -0,0 +1,238 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [
|
||||
0x1a1d063e54b1e764b63e1855bff015b8cedd192f47308731499573f23597d4b5,
|
||||
0x26abc66f3fdf8e68839d10956259063708235dccc1aa3793b91b002c5b257c37,
|
||||
0x0c7c64a9d887385381a578cfed5aed370754427aabca92a70b3c2b12ff4d7be8,
|
||||
0x1cf5998769e9fab79e17f0b6d08b2d1eba2ebac30dc386b0edd383831354b495,
|
||||
0x0f5e3a8566be31b7564ca60461e9e08b19828764a9669bc17aba0b97e66b0109,
|
||||
0x18df6a9d19ea90d895e60e4db0794a01f359a53a180b7d4b42bf3d7a531c976e,
|
||||
0x04f7bf2c5c0538ac6e4b782c3c6e601ad0ea1d3a3b9d25ef4e324055fa3123dc,
|
||||
0x29c76ce22255206e3c40058523748531e770c0584aa2328ce55d54628b89ebe6,
|
||||
0x198d425a45b78e85c053659ab4347f5d65b1b8e9c6108dbe00e0e945dbc5ff15,
|
||||
0x25ee27ab6296cd5e6af3cc79c598a1daa7ff7f6878b3c49d49d3a9a90c3fdf74,
|
||||
0x138ea8e0af41a1e024561001c0b6eb1505845d7d0c55b1b2c0f88687a96d1381,
|
||||
0x306197fb3fab671ef6e7c2cba2eefd0e42851b5b9811f2ca4013370a01d95687,
|
||||
0x1a0c7d52dc32a4432b66f0b4894d4f1a21db7565e5b4250486419eaf00e8f620,
|
||||
0x2b46b418de80915f3ff86a8e5c8bdfccebfbe5f55163cd6caa52997da2c54a9f,
|
||||
0x12d3e0dc0085873701f8b777b9673af9613a1af5db48e05bfb46e312b5829f64,
|
||||
0x263390cf74dc3a8870f5002ed21d089ffb2bf768230f648dba338a5cb19b3a1f,
|
||||
0x0a14f33a5fe668a60ac884b4ca607ad0f8abb5af40f96f1d7d543db52b003dcd,
|
||||
0x28ead9c586513eab1a5e86509d68b2da27be3a4f01171a1dd847df829bc683b9,
|
||||
0x1c6ab1c328c3c6430972031f1bdb2ac9888f0ea1abe71cffea16cda6e1a7416c,
|
||||
0x1fc7e71bc0b819792b2500239f7f8de04f6decd608cb98a932346015c5b42c94,
|
||||
0x03e107eb3a42b2ece380e0d860298f17c0c1e197c952650ee6dd85b93a0ddaa8,
|
||||
0x2d354a251f381a4669c0d52bf88b772c46452ca57c08697f454505f6941d78cd,
|
||||
0x094af88ab05d94baf687ef14bc566d1c522551d61606eda3d14b4606826f794b,
|
||||
0x19705b783bf3d2dc19bcaeabf02f8ca5e1ab5b6f2e3195a9d52b2d249d1396f7,
|
||||
0x09bf4acc3a8bce3f1fcc33fee54fc5b28723b16b7d740a3e60cef6852271200e,
|
||||
0x1803f8200db6013c50f83c0c8fab62843413732f301f7058543a073f3f3b5e4e,
|
||||
0x0f80afb5046244de30595b160b8d1f38bf6fb02d4454c0add41f7fef2faf3e5c,
|
||||
0x126ee1f8504f15c3d77f0088c1cfc964abcfcf643f4a6fea7dc3f98219529d78,
|
||||
0x23c203d10cfcc60f69bfb3d919552ca10ffb4ee63175ddf8ef86f991d7d0a591,
|
||||
0x2a2ae15d8b143709ec0d09705fa3a6303dec1ee4eec2cf747c5a339f7744fb94,
|
||||
0x07b60dee586ed6ef47e5c381ab6343ecc3d3b3006cb461bbb6b5d89081970b2b,
|
||||
0x27316b559be3edfd885d95c494c1ae3d8a98a320baa7d152132cfe583c9311bd,
|
||||
0x1d5c49ba157c32b8d8937cb2d3f84311ef834cc2a743ed662f5f9af0c0342e76,
|
||||
0x2f8b124e78163b2f332774e0b850b5ec09c01bf6979938f67c24bd5940968488,
|
||||
0x1e6843a5457416b6dc5b7aa09a9ce21b1d4cba6554e51d84665f75260113b3d5,
|
||||
0x11cdf00a35f650c55fca25c9929c8ad9a68daf9ac6a189ab1f5bc79f21641d4b,
|
||||
0x21632de3d3bbc5e42ef36e588158d6d4608b2815c77355b7e82b5b9b7eb560bc,
|
||||
0x0de625758452efbd97b27025fbd245e0255ae48ef2a329e449d7b5c51c18498a,
|
||||
0x2ad253c053e75213e2febfd4d976cc01dd9e1e1c6f0fb6b09b09546ba0838098,
|
||||
0x1d6b169ed63872dc6ec7681ec39b3be93dd49cdd13c813b7d35702e38d60b077,
|
||||
0x1660b740a143664bb9127c4941b67fed0be3ea70a24d5568c3a54e706cfef7fe,
|
||||
0x0065a92d1de81f34114f4ca2deef76e0ceacdddb12cf879096a29f10376ccbfe,
|
||||
0x1f11f065202535987367f823da7d672c353ebe2ccbc4869bcf30d50a5871040d,
|
||||
0x26596f5c5dd5a5d1b437ce7b14a2c3dd3bd1d1a39b6759ba110852d17df0693e,
|
||||
0x16f49bc727e45a2f7bf3056efcf8b6d38539c4163a5f1e706743db15af91860f,
|
||||
0x1abe1deb45b3e3119954175efb331bf4568feaf7ea8b3dc5e1a4e7438dd39e5f,
|
||||
0x0e426ccab66984d1d8993a74ca548b779f5db92aaec5f102020d34aea15fba59,
|
||||
0x0e7c30c2e2e8957f4933bd1942053f1f0071684b902d534fa841924303f6a6c6,
|
||||
0x0812a017ca92cf0a1622708fc7edff1d6166ded6e3528ead4c76e1f31d3fc69d,
|
||||
0x21a5ade3df2bc1b5bba949d1db96040068afe5026edd7a9c2e276b47cf010d54,
|
||||
0x01f3035463816c84ad711bf1a058c6c6bd101945f50e5afe72b1a5233f8749ce,
|
||||
0x0b115572f038c0e2028c2aafc2d06a5e8bf2f9398dbd0fdf4dcaa82b0f0c1c8b,
|
||||
0x1c38ec0b99b62fd4f0ef255543f50d2e27fc24db42bc910a3460613b6ef59e2f,
|
||||
0x1c89c6d9666272e8425c3ff1f4ac737b2f5d314606a297d4b1d0b254d880c53e,
|
||||
0x03326e643580356bf6d44008ae4c042a21ad4880097a5eb38b71e2311bb88f8f,
|
||||
0x268076b0054fb73f67cee9ea0e51e3ad50f27a6434b5dceb5bdde2299910a4c9,
|
||||
]
|
||||
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [F(0x1d066a255517b7fd8bddd3a93f7804ef7f8fcde48bb4c37a59a09a1a97052816)
|
||||
, F(0x29daefb55f6f2dc6ac3f089cebcc6120b7c6fef31367b68eb7238547d32c1610)
|
||||
, F(0x1f2cb1624a78ee001ecbd88ad959d7012572d76f08ec5c4f9e8b7ad7b0b4e1d1)
|
||||
]
|
||||
, [ F(0x0aad2e79f15735f2bd77c0ed3d14aa27b11f092a53bbc6e1db0672ded84f31e5)
|
||||
, F(0x2252624f8617738cd6f661dd4094375f37028a98f1dece66091ccf1595b43f28)
|
||||
, F(0x1a24913a928b38485a65a84a291da1ff91c20626524b2b87d49f4f2c9018d735)
|
||||
]
|
||||
, [ F(0x22fc468f1759b74d7bfc427b5f11ebb10a41515ddff497b14fd6dae1508fc47a)
|
||||
, F(0x1059ca787f1f89ed9cd026e9c9ca107ae61956ff0b4121d5efd65515617f6e4d)
|
||||
, F(0x02be9473358461d8f61f3536d877de982123011f0bf6f155a45cbbfae8b981ce)
|
||||
]
|
||||
, [ F(0x0ec96c8e32962d462778a749c82ed623aba9b669ac5b8736a1ff3a441a5084a4)
|
||||
, F(0x292f906e073677405442d9553c45fa3f5a47a7cdb8c99f9648fb2e4d814df57e)
|
||||
, F(0x274982444157b86726c11b9a0f5e39a5cc611160a394ea460c63f0b2ffe5657e)
|
||||
]
|
||||
, [ F(0x1acd63c67fbc9ab1626ed93491bda32e5da18ea9d8e4f10178d04aa6f8747ad0)
|
||||
, F(0x19f8a5d670e8ab66c4e3144be58ef6901bf93375e2323ec3ca8c86cd2a28b5a5)
|
||||
, F(0x1c0dc443519ad7a86efa40d2df10a011068193ea51f6c92ae1cfbb5f7b9b6893)
|
||||
]
|
||||
, [ F(0x14b39e7aa4068dbe50fe7190e421dc19fbeab33cb4f6a2c4180e4c3224987d3d)
|
||||
, F(0x1d449b71bd826ec58f28c63ea6c561b7b820fc519f01f021afb1e35e28b0795e)
|
||||
, F(0x1ea2c9a89baaddbb60fa97fe60fe9d8e89de141689d1252276524dc0a9e987fc)
|
||||
]
|
||||
, [ F(0x0478d66d43535a8cb57e9c1c3d6a2bd7591f9a46a0e9c058134d5cefdb3c7ff1)
|
||||
, F(0x19272db71eece6a6f608f3b2717f9cd2662e26ad86c400b21cde5e4a7b00bebe)
|
||||
, F(0x14226537335cab33c749c746f09208abb2dd1bd66a87ef75039be846af134166)
|
||||
]
|
||||
, [ F(0x01fd6af15956294f9dfe38c0d976a088b21c21e4a1c2e823f912f44961f9a9ce)
|
||||
, F(0x18e5abedd626ec307bca190b8b2cab1aaee2e62ed229ba5a5ad8518d4e5f2a57)
|
||||
, F(0x0fc1bbceba0590f5abbdffa6d3b35e3297c021a3a409926d0e2d54dc1c84fda6)
|
||||
]]
|
||||
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(0)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
|
||||
|
||||
|
||||
secret_voucher = F(randrange(0,p,1))
|
||||
reward_voucher = poseidon2_hash([F(1668646695034522932676805048878418),secret_voucher])
|
||||
|
||||
merkle_nodes = [F(randrange(0,p,1)) for i in range(32)]
|
||||
selectors = randrange(0,2**32,1)
|
||||
selectors = format(selectors,'032b')
|
||||
voucher_root = reward_voucher
|
||||
for i in range(32):
|
||||
if int(selectors[31-i]) == 0:
|
||||
voucher_root = poseidon2_hash([voucher_root,merkle_nodes[i]])
|
||||
else:
|
||||
voucher_root = poseidon2_hash([merkle_nodes[i],voucher_root])
|
||||
|
||||
data_msg = F(randrange(0,p,1))
|
||||
|
||||
inp = {
|
||||
"secret_voucher": str(secret_voucher),
|
||||
"voucher_merkle_path":[str(x) for x in merkle_nodes],
|
||||
"voucher_merkle_path_selectors": [str(x) for x in selectors],
|
||||
"mantle_tx_hash": str(data_msg),
|
||||
"voucher_root": str(voucher_root)
|
||||
}
|
||||
|
||||
import json
|
||||
|
||||
with open("input.json","w") as f:
|
||||
json.dump(inp, f, indent=2)
|
||||
|
||||
print("Wrote input of proof of claim")
|
||||
232
mantle/generate_inputs_for_signature.py
Executable file
232
mantle/generate_inputs_for_signature.py
Executable file
@ -0,0 +1,232 @@
|
||||
#!/usr/bin/sage
|
||||
# -*- mode: python ; -*-
|
||||
|
||||
|
||||
from sage.all import *
|
||||
|
||||
p = 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
||||
F = FiniteField(p)
|
||||
|
||||
def poseidon2_hash(data):
|
||||
return PoseidonSponge(data,2,1)[0]
|
||||
|
||||
|
||||
|
||||
def Poseidon2_sponge_hash_rate_1(data, n):
|
||||
return PoseidonSponge(data,3,2,n,1)
|
||||
|
||||
def Poseidon2_sponge_hash_rate_2(data, n):
|
||||
return PoseidonSponge(data,3,1,n,1)
|
||||
|
||||
|
||||
def SBox(inp):
|
||||
return inp**5
|
||||
|
||||
def InternalRound(inp, i):
|
||||
round_consts = [
|
||||
0x1a1d063e54b1e764b63e1855bff015b8cedd192f47308731499573f23597d4b5,
|
||||
0x26abc66f3fdf8e68839d10956259063708235dccc1aa3793b91b002c5b257c37,
|
||||
0x0c7c64a9d887385381a578cfed5aed370754427aabca92a70b3c2b12ff4d7be8,
|
||||
0x1cf5998769e9fab79e17f0b6d08b2d1eba2ebac30dc386b0edd383831354b495,
|
||||
0x0f5e3a8566be31b7564ca60461e9e08b19828764a9669bc17aba0b97e66b0109,
|
||||
0x18df6a9d19ea90d895e60e4db0794a01f359a53a180b7d4b42bf3d7a531c976e,
|
||||
0x04f7bf2c5c0538ac6e4b782c3c6e601ad0ea1d3a3b9d25ef4e324055fa3123dc,
|
||||
0x29c76ce22255206e3c40058523748531e770c0584aa2328ce55d54628b89ebe6,
|
||||
0x198d425a45b78e85c053659ab4347f5d65b1b8e9c6108dbe00e0e945dbc5ff15,
|
||||
0x25ee27ab6296cd5e6af3cc79c598a1daa7ff7f6878b3c49d49d3a9a90c3fdf74,
|
||||
0x138ea8e0af41a1e024561001c0b6eb1505845d7d0c55b1b2c0f88687a96d1381,
|
||||
0x306197fb3fab671ef6e7c2cba2eefd0e42851b5b9811f2ca4013370a01d95687,
|
||||
0x1a0c7d52dc32a4432b66f0b4894d4f1a21db7565e5b4250486419eaf00e8f620,
|
||||
0x2b46b418de80915f3ff86a8e5c8bdfccebfbe5f55163cd6caa52997da2c54a9f,
|
||||
0x12d3e0dc0085873701f8b777b9673af9613a1af5db48e05bfb46e312b5829f64,
|
||||
0x263390cf74dc3a8870f5002ed21d089ffb2bf768230f648dba338a5cb19b3a1f,
|
||||
0x0a14f33a5fe668a60ac884b4ca607ad0f8abb5af40f96f1d7d543db52b003dcd,
|
||||
0x28ead9c586513eab1a5e86509d68b2da27be3a4f01171a1dd847df829bc683b9,
|
||||
0x1c6ab1c328c3c6430972031f1bdb2ac9888f0ea1abe71cffea16cda6e1a7416c,
|
||||
0x1fc7e71bc0b819792b2500239f7f8de04f6decd608cb98a932346015c5b42c94,
|
||||
0x03e107eb3a42b2ece380e0d860298f17c0c1e197c952650ee6dd85b93a0ddaa8,
|
||||
0x2d354a251f381a4669c0d52bf88b772c46452ca57c08697f454505f6941d78cd,
|
||||
0x094af88ab05d94baf687ef14bc566d1c522551d61606eda3d14b4606826f794b,
|
||||
0x19705b783bf3d2dc19bcaeabf02f8ca5e1ab5b6f2e3195a9d52b2d249d1396f7,
|
||||
0x09bf4acc3a8bce3f1fcc33fee54fc5b28723b16b7d740a3e60cef6852271200e,
|
||||
0x1803f8200db6013c50f83c0c8fab62843413732f301f7058543a073f3f3b5e4e,
|
||||
0x0f80afb5046244de30595b160b8d1f38bf6fb02d4454c0add41f7fef2faf3e5c,
|
||||
0x126ee1f8504f15c3d77f0088c1cfc964abcfcf643f4a6fea7dc3f98219529d78,
|
||||
0x23c203d10cfcc60f69bfb3d919552ca10ffb4ee63175ddf8ef86f991d7d0a591,
|
||||
0x2a2ae15d8b143709ec0d09705fa3a6303dec1ee4eec2cf747c5a339f7744fb94,
|
||||
0x07b60dee586ed6ef47e5c381ab6343ecc3d3b3006cb461bbb6b5d89081970b2b,
|
||||
0x27316b559be3edfd885d95c494c1ae3d8a98a320baa7d152132cfe583c9311bd,
|
||||
0x1d5c49ba157c32b8d8937cb2d3f84311ef834cc2a743ed662f5f9af0c0342e76,
|
||||
0x2f8b124e78163b2f332774e0b850b5ec09c01bf6979938f67c24bd5940968488,
|
||||
0x1e6843a5457416b6dc5b7aa09a9ce21b1d4cba6554e51d84665f75260113b3d5,
|
||||
0x11cdf00a35f650c55fca25c9929c8ad9a68daf9ac6a189ab1f5bc79f21641d4b,
|
||||
0x21632de3d3bbc5e42ef36e588158d6d4608b2815c77355b7e82b5b9b7eb560bc,
|
||||
0x0de625758452efbd97b27025fbd245e0255ae48ef2a329e449d7b5c51c18498a,
|
||||
0x2ad253c053e75213e2febfd4d976cc01dd9e1e1c6f0fb6b09b09546ba0838098,
|
||||
0x1d6b169ed63872dc6ec7681ec39b3be93dd49cdd13c813b7d35702e38d60b077,
|
||||
0x1660b740a143664bb9127c4941b67fed0be3ea70a24d5568c3a54e706cfef7fe,
|
||||
0x0065a92d1de81f34114f4ca2deef76e0ceacdddb12cf879096a29f10376ccbfe,
|
||||
0x1f11f065202535987367f823da7d672c353ebe2ccbc4869bcf30d50a5871040d,
|
||||
0x26596f5c5dd5a5d1b437ce7b14a2c3dd3bd1d1a39b6759ba110852d17df0693e,
|
||||
0x16f49bc727e45a2f7bf3056efcf8b6d38539c4163a5f1e706743db15af91860f,
|
||||
0x1abe1deb45b3e3119954175efb331bf4568feaf7ea8b3dc5e1a4e7438dd39e5f,
|
||||
0x0e426ccab66984d1d8993a74ca548b779f5db92aaec5f102020d34aea15fba59,
|
||||
0x0e7c30c2e2e8957f4933bd1942053f1f0071684b902d534fa841924303f6a6c6,
|
||||
0x0812a017ca92cf0a1622708fc7edff1d6166ded6e3528ead4c76e1f31d3fc69d,
|
||||
0x21a5ade3df2bc1b5bba949d1db96040068afe5026edd7a9c2e276b47cf010d54,
|
||||
0x01f3035463816c84ad711bf1a058c6c6bd101945f50e5afe72b1a5233f8749ce,
|
||||
0x0b115572f038c0e2028c2aafc2d06a5e8bf2f9398dbd0fdf4dcaa82b0f0c1c8b,
|
||||
0x1c38ec0b99b62fd4f0ef255543f50d2e27fc24db42bc910a3460613b6ef59e2f,
|
||||
0x1c89c6d9666272e8425c3ff1f4ac737b2f5d314606a297d4b1d0b254d880c53e,
|
||||
0x03326e643580356bf6d44008ae4c042a21ad4880097a5eb38b71e2311bb88f8f,
|
||||
0x268076b0054fb73f67cee9ea0e51e3ad50f27a6434b5dceb5bdde2299910a4c9,
|
||||
]
|
||||
|
||||
|
||||
sb = SBox(inp[0] + round_consts[i])
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*sb + inp[1] + inp[2];
|
||||
out[1] = sb + 2*inp[1] + inp[2];
|
||||
out[2] = sb + inp[1] + 3*inp[2];
|
||||
return out
|
||||
|
||||
def ExternalRound(inp, i):
|
||||
out = [F(0) for j in range(3)]
|
||||
round_consts = [ [F(0x1d066a255517b7fd8bddd3a93f7804ef7f8fcde48bb4c37a59a09a1a97052816)
|
||||
, F(0x29daefb55f6f2dc6ac3f089cebcc6120b7c6fef31367b68eb7238547d32c1610)
|
||||
, F(0x1f2cb1624a78ee001ecbd88ad959d7012572d76f08ec5c4f9e8b7ad7b0b4e1d1)
|
||||
]
|
||||
, [ F(0x0aad2e79f15735f2bd77c0ed3d14aa27b11f092a53bbc6e1db0672ded84f31e5)
|
||||
, F(0x2252624f8617738cd6f661dd4094375f37028a98f1dece66091ccf1595b43f28)
|
||||
, F(0x1a24913a928b38485a65a84a291da1ff91c20626524b2b87d49f4f2c9018d735)
|
||||
]
|
||||
, [ F(0x22fc468f1759b74d7bfc427b5f11ebb10a41515ddff497b14fd6dae1508fc47a)
|
||||
, F(0x1059ca787f1f89ed9cd026e9c9ca107ae61956ff0b4121d5efd65515617f6e4d)
|
||||
, F(0x02be9473358461d8f61f3536d877de982123011f0bf6f155a45cbbfae8b981ce)
|
||||
]
|
||||
, [ F(0x0ec96c8e32962d462778a749c82ed623aba9b669ac5b8736a1ff3a441a5084a4)
|
||||
, F(0x292f906e073677405442d9553c45fa3f5a47a7cdb8c99f9648fb2e4d814df57e)
|
||||
, F(0x274982444157b86726c11b9a0f5e39a5cc611160a394ea460c63f0b2ffe5657e)
|
||||
]
|
||||
, [ F(0x1acd63c67fbc9ab1626ed93491bda32e5da18ea9d8e4f10178d04aa6f8747ad0)
|
||||
, F(0x19f8a5d670e8ab66c4e3144be58ef6901bf93375e2323ec3ca8c86cd2a28b5a5)
|
||||
, F(0x1c0dc443519ad7a86efa40d2df10a011068193ea51f6c92ae1cfbb5f7b9b6893)
|
||||
]
|
||||
, [ F(0x14b39e7aa4068dbe50fe7190e421dc19fbeab33cb4f6a2c4180e4c3224987d3d)
|
||||
, F(0x1d449b71bd826ec58f28c63ea6c561b7b820fc519f01f021afb1e35e28b0795e)
|
||||
, F(0x1ea2c9a89baaddbb60fa97fe60fe9d8e89de141689d1252276524dc0a9e987fc)
|
||||
]
|
||||
, [ F(0x0478d66d43535a8cb57e9c1c3d6a2bd7591f9a46a0e9c058134d5cefdb3c7ff1)
|
||||
, F(0x19272db71eece6a6f608f3b2717f9cd2662e26ad86c400b21cde5e4a7b00bebe)
|
||||
, F(0x14226537335cab33c749c746f09208abb2dd1bd66a87ef75039be846af134166)
|
||||
]
|
||||
, [ F(0x01fd6af15956294f9dfe38c0d976a088b21c21e4a1c2e823f912f44961f9a9ce)
|
||||
, F(0x18e5abedd626ec307bca190b8b2cab1aaee2e62ed229ba5a5ad8518d4e5f2a57)
|
||||
, F(0x0fc1bbceba0590f5abbdffa6d3b35e3297c021a3a409926d0e2d54dc1c84fda6)
|
||||
]]
|
||||
|
||||
|
||||
sb = [F(0) for j in range(3)]
|
||||
for j in range(3):
|
||||
sb[j] = SBox(F(inp[j] + round_consts[i][j]))
|
||||
out = [F(0) for j in range(3)]
|
||||
out[0] = 2*sb[0] + sb[1] + sb[2]
|
||||
out[1] = sb[0] + 2*sb[1] + sb[2]
|
||||
out[2] = sb[0]+ sb[1] + 2*sb[2]
|
||||
return out
|
||||
|
||||
def LinearLayer(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
out[0] = 2*inp[0] + inp[1] + inp[2]
|
||||
out[1] = inp[0] + 2*inp[1] + inp[2]
|
||||
out[2] = inp[0] + inp[1] + 2*inp[2]
|
||||
return out
|
||||
|
||||
def Permutation(inp):
|
||||
out = [F(0) for i in range(3)]
|
||||
|
||||
state = LinearLayer(inp)
|
||||
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k)
|
||||
for k in range(56):
|
||||
state = InternalRound(state, k)
|
||||
for k in range(4):
|
||||
state = ExternalRound(state, k+4)
|
||||
return state
|
||||
|
||||
def Compression(inp):
|
||||
return Permutation([inp[0],inp[1],F(0)])
|
||||
|
||||
def PoseidonSponge(data, capacity, output_len):
|
||||
rate = 3 - capacity;
|
||||
output = [F(0) for i in range(output_len)]
|
||||
assert( capacity > 0 )
|
||||
assert( rate > 0 )
|
||||
assert( capacity < 3 )
|
||||
assert( rate < 3 )
|
||||
|
||||
# round up to rate the input + 1 field element ("10*" padding)
|
||||
nblocks = ((len(data) + 1) + (rate-1)) // rate;
|
||||
nout = (output_len + (rate-1)) // rate;
|
||||
padded_len = nblocks * rate;
|
||||
|
||||
padded = []
|
||||
for i in range(len(data)):
|
||||
padded.append(F(data[i]))
|
||||
padded.append(F(1))
|
||||
for i in range(len(data)+1,padded_len):
|
||||
padded.append(F(0))
|
||||
|
||||
civ = F(0)
|
||||
|
||||
state = [F(0),F(0),F(civ)]
|
||||
sorbed = [F(0) for j in range(rate)]
|
||||
|
||||
for m in range(nblocks):
|
||||
for i in range(rate):
|
||||
a = state[i]
|
||||
b = padded[m*rate+i]
|
||||
sorbed[i] = a + b
|
||||
state = Permutation(sorbed[0:rate] + state[rate:3])
|
||||
|
||||
q = min(rate, output_len)
|
||||
for i in range(q):
|
||||
output[i] = state[i]
|
||||
out_ptr = rate
|
||||
|
||||
for n in range(1,nout):
|
||||
state[nblocks+n] = Permutation(state[nblocks+n-1])
|
||||
q = min(rate, output_len-out_ptr)
|
||||
for i in range(q):
|
||||
output[out_ptr+i] = state[nblocks+n][i]
|
||||
out_ptr += rate
|
||||
|
||||
return output
|
||||
|
||||
if len(sys.argv) != Integer(2):
|
||||
print("Usage: <script> <number of input>")
|
||||
exit()
|
||||
|
||||
nInput = int(sys.argv[Integer(1)])
|
||||
sk = [F(randrange(0,p,1)) for i in range(nInput)]
|
||||
|
||||
data_msg = F(randrange(0,p,1))
|
||||
|
||||
if nInput == 1:
|
||||
inp = {
|
||||
"secret_keys": str(sk[0]),
|
||||
"msg": str(data_msg)
|
||||
}
|
||||
else:
|
||||
inp = {
|
||||
"secret_keys": [str(x) for x in sk],
|
||||
"msg": str(data_msg)
|
||||
}
|
||||
|
||||
import json
|
||||
|
||||
with open("input.json","w") as f:
|
||||
json.dump(inp, f, indent=2)
|
||||
|
||||
print("Wrote input of ZkSignature")
|
||||
74
mantle/poc.circom
Normal file
74
mantle/poc.circom
Normal file
@ -0,0 +1,74 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../hash_bn/poseidon2_hash.circom";
|
||||
include "../hash_bn/merkle.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template derive_voucher_nullifier(){
|
||||
signal input secret_voucher;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(2);
|
||||
component dst = VOUCHER_NF();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== secret_voucher;
|
||||
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
template derive_reward_voucher(){
|
||||
signal input secret_voucher;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(2);
|
||||
component dst = REWARD_VOUCHER();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== secret_voucher;
|
||||
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
template proof_of_claim(){
|
||||
signal input secret_voucher;
|
||||
signal input voucher_merkle_path[32];
|
||||
signal input voucher_merkle_path_selectors[32];
|
||||
signal input mantle_tx_hash;
|
||||
signal input voucher_root;
|
||||
|
||||
signal output voucher_nullifier;
|
||||
|
||||
//derive the reward voucher
|
||||
component reward_voucher = derive_reward_voucher();
|
||||
reward_voucher.secret_voucher <== secret_voucher;
|
||||
|
||||
//Check reward voucher membership
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
voucher_merkle_path_selectors[i] * (1 - voucher_merkle_path_selectors[i]) === 0;
|
||||
}
|
||||
//Then check the proof of membership
|
||||
component reward_membership = proof_of_membership(32);
|
||||
for(var i = 0; i < 32; i++){
|
||||
reward_membership.nodes[i] <== voucher_merkle_path[i];
|
||||
reward_membership.selector[i] <== voucher_merkle_path_selectors[i];
|
||||
}
|
||||
reward_membership.root <== voucher_root;
|
||||
reward_membership.leaf <== reward_voucher.out;
|
||||
|
||||
reward_membership.out === 1;
|
||||
|
||||
|
||||
//derive the reward nullifier
|
||||
component reward_nullifier = derive_voucher_nullifier();
|
||||
reward_nullifier.secret_voucher <== secret_voucher;
|
||||
voucher_nullifier <== reward_nullifier.out;
|
||||
|
||||
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== mantle_tx_hash * mantle_tx_hash;
|
||||
}
|
||||
|
||||
component main {public [voucher_root,mantle_tx_hash]}= proof_of_claim();
|
||||
5
mantle/pol.circom
Normal file
5
mantle/pol.circom
Normal file
@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "pol_lib.circom";
|
||||
|
||||
component main {public [sl,epoch_nonce,t0,t1,ledger_aged,ledger_latest,P_lead_part_one,P_lead_part_two]}= proof_of_leadership(25);
|
||||
248
mantle/pol_lib.circom
Normal file
248
mantle/pol_lib.circom
Normal file
@ -0,0 +1,248 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../hash_bn/poseidon2_hash.circom";
|
||||
include "../ledger/notes.circom";
|
||||
include "../hash_bn/merkle.circom";
|
||||
include "../misc/comparator.circom";
|
||||
include "../circomlib/circuits/bitify.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
|
||||
template ticket_calculator(){
|
||||
signal input epoch_nonce;
|
||||
signal input slot;
|
||||
signal input note_id;
|
||||
signal input secret_key;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(5);
|
||||
component dst = LEAD_V1();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== epoch_nonce;
|
||||
hash.inp[2] <== slot;
|
||||
hash.inp[3] <== note_id;
|
||||
hash.inp[4] <== secret_key;
|
||||
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
template derive_entropy(){
|
||||
signal input slot;
|
||||
signal input note_id;
|
||||
signal input secret_key;
|
||||
signal output out;
|
||||
|
||||
component hash = Poseidon2_hash(4);
|
||||
component dst = NOMOS_NONCE_CONTRIB_V1();
|
||||
hash.inp[0] <== dst.out;
|
||||
hash.inp[1] <== slot;
|
||||
hash.inp[2] <== note_id;
|
||||
hash.inp[3] <== secret_key;
|
||||
|
||||
out <== hash.out;
|
||||
}
|
||||
|
||||
template would_win_leadership(secret_depth){
|
||||
signal input slot;
|
||||
signal input epoch_nonce;
|
||||
signal input t0;
|
||||
signal input t1;
|
||||
signal input slot_secret;
|
||||
signal input slot_secret_path[secret_depth];
|
||||
|
||||
//Part of the note id proof of membership to prove aged
|
||||
signal input aged_nodes[32];
|
||||
signal input aged_selectors[32]; // must be bits
|
||||
signal input aged_root;
|
||||
|
||||
//Used to derive the note identifier
|
||||
signal input transaction_hash;
|
||||
signal input output_number;
|
||||
|
||||
//Part of the secret key
|
||||
signal input starting_slot;
|
||||
|
||||
// The winning note value
|
||||
signal input value;
|
||||
|
||||
signal output out;
|
||||
signal output note_identifier;
|
||||
signal output secret_key;
|
||||
|
||||
|
||||
// Derivation of the secrets root from the slot secret at position slot - starting_slot
|
||||
// Verify that the substraction wont underflow (starting_slot < slot)
|
||||
component checker = SafeFullLessThan();
|
||||
checker.a <== starting_slot;
|
||||
checker.b <== slot;
|
||||
|
||||
// Compute the positions related to slot - starting_slot and make sure slot - starting_slot is a 25 bits number
|
||||
component bits = Num2Bits(secret_depth);
|
||||
bits.in <== slot - starting_slot;
|
||||
|
||||
// Derive the secrets root
|
||||
component secrets_root = compute_merkle_root(secret_depth);
|
||||
for(var i=0; i<secret_depth; i++){
|
||||
secrets_root.nodes[i] <== slot_secret_path[i];
|
||||
secrets_root.selector[i] <== bits.out[secret_depth-1-i];
|
||||
}
|
||||
secrets_root.leaf <== slot_secret;
|
||||
|
||||
|
||||
// Derive the secret key
|
||||
component sk = derive_secret_key();
|
||||
sk.starting_slot <== starting_slot;
|
||||
sk.secrets_root <== secrets_root.root;
|
||||
|
||||
|
||||
// Derive the public key from the secret key
|
||||
component pk = derive_public_key();
|
||||
pk.secret_key <== sk.out;
|
||||
|
||||
|
||||
// Derive the note id
|
||||
component note_id = Poseidon2_hash(5);
|
||||
component dst_note_id = NOMOS_NOTE_ID_V1();
|
||||
note_id.inp[0] <== dst_note_id.out;
|
||||
note_id.inp[1] <== transaction_hash;
|
||||
note_id.inp[2] <== output_number;
|
||||
note_id.inp[3] <== value;
|
||||
note_id.inp[4] <== pk.out;
|
||||
|
||||
|
||||
// Check the note ID is aged enough
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
aged_selectors[i] * (1 - aged_selectors[i]) === 0;
|
||||
}
|
||||
//Then check the proof of membership
|
||||
component aged_membership = proof_of_membership(32);
|
||||
for(var i = 0; i < 32; i++){
|
||||
aged_membership.nodes[i] <== aged_nodes[i];
|
||||
aged_membership.selector[i] <== aged_selectors[i];
|
||||
}
|
||||
aged_membership.root <== aged_root;
|
||||
aged_membership.leaf <== note_id.out;
|
||||
|
||||
|
||||
// Compute the lottery ticket
|
||||
component ticket = ticket_calculator();
|
||||
ticket.epoch_nonce <== epoch_nonce;
|
||||
ticket.slot <== slot;
|
||||
ticket.note_id <== note_id.out;
|
||||
ticket.secret_key <== sk.out;
|
||||
|
||||
|
||||
// Compute the lottery threshold
|
||||
signal intermediate;
|
||||
signal threshold;
|
||||
intermediate <== t1 * value;
|
||||
threshold <== value * (t0 + intermediate);
|
||||
|
||||
|
||||
// Check that the ticket is winning
|
||||
component winning = SafeFullLessThan();
|
||||
winning.a <== ticket.out;
|
||||
winning.b <== threshold;
|
||||
|
||||
// Check that every constraint holds
|
||||
signal intermediate_out;
|
||||
intermediate_out <== aged_membership.out * winning.out;
|
||||
out <== intermediate_out * checker.out;
|
||||
|
||||
note_identifier <== note_id.out;
|
||||
secret_key <== sk.out;
|
||||
}
|
||||
|
||||
|
||||
template proof_of_leadership(secret_depth){
|
||||
signal input sl;
|
||||
signal input epoch_nonce; // the epoch nonce eta
|
||||
signal input t0;
|
||||
signal input t1;
|
||||
signal input slot_secret; // This is r_sl
|
||||
signal input slot_secret_path[secret_depth];
|
||||
|
||||
//Part of the note id proof of membership to prove aged
|
||||
signal input noteid_aged_path[32];
|
||||
signal input noteid_aged_selectors[32]; // must be bits
|
||||
signal input ledger_aged;
|
||||
|
||||
//Used to derive the note identifier
|
||||
signal input note_tx_hash;
|
||||
signal input note_output_number;
|
||||
|
||||
//Part of the note id proof of membership to prove it's unspent
|
||||
signal input noteid_latest_path[32];
|
||||
signal input noteid_latest_selectors[32]; // must be bits
|
||||
signal input ledger_latest;
|
||||
|
||||
//Part of the secret key
|
||||
signal input starting_slot;
|
||||
|
||||
// The winning note. The unit is supposed to be NMO and the ZoneID is MANTLE
|
||||
signal input v; // value of the note
|
||||
|
||||
|
||||
// Verify the note is winning the lottery
|
||||
component lottery_checker = would_win_leadership(secret_depth);
|
||||
lottery_checker.slot <== sl;
|
||||
lottery_checker.epoch_nonce <== epoch_nonce;
|
||||
lottery_checker.t0 <== t0;
|
||||
lottery_checker.t1 <== t1;
|
||||
lottery_checker.slot_secret <== slot_secret;
|
||||
for(var i = 0; i < secret_depth; i++){
|
||||
lottery_checker.slot_secret_path[i] <== slot_secret_path[i];
|
||||
}
|
||||
for(var i = 0; i < 32; i++){
|
||||
lottery_checker.aged_nodes[i] <== noteid_aged_path[i];
|
||||
lottery_checker.aged_selectors[i] <== noteid_aged_selectors[i];
|
||||
}
|
||||
lottery_checker.aged_root <== ledger_aged;
|
||||
lottery_checker.transaction_hash <== note_tx_hash;
|
||||
lottery_checker.output_number <== note_output_number;
|
||||
lottery_checker.starting_slot <== starting_slot;
|
||||
lottery_checker.value <== v;
|
||||
|
||||
|
||||
// One time signing key used to sign the block proposal and the block
|
||||
signal input P_lead_part_one;
|
||||
signal input P_lead_part_two;
|
||||
|
||||
|
||||
//Avoid the circom optimisation that removes unused public input
|
||||
signal dummy_one;
|
||||
signal dummy_two;
|
||||
dummy_one <== P_lead_part_one * P_lead_part_one;
|
||||
dummy_two <== P_lead_part_two * P_lead_part_two;
|
||||
|
||||
signal output entropy_contribution; // This is rho_lead
|
||||
|
||||
|
||||
// Check that the note is unspent
|
||||
//First check selectors are indeed bits
|
||||
for(var i = 0; i < 32; i++){
|
||||
noteid_latest_selectors[i] * (1 - noteid_latest_selectors[i]) === 0;
|
||||
}
|
||||
//Then check the note id is in the latest ledger state
|
||||
component unspent_membership = proof_of_membership(32);
|
||||
for(var i = 0; i < 32; i++){
|
||||
unspent_membership.nodes[i] <== noteid_latest_path[i];
|
||||
unspent_membership.selector[i] <== noteid_latest_selectors[i];
|
||||
}
|
||||
unspent_membership.root <== ledger_latest;
|
||||
unspent_membership.leaf <== lottery_checker.note_identifier;
|
||||
|
||||
lottery_checker.out * unspent_membership.out === 1;
|
||||
|
||||
|
||||
// Compute the entropy contribution
|
||||
component entropy = derive_entropy();
|
||||
entropy.slot <== sl;
|
||||
entropy.note_id <== lottery_checker.note_identifier;
|
||||
entropy.secret_key <== lottery_checker.secret_key;
|
||||
|
||||
entropy_contribution <== entropy.out;
|
||||
}
|
||||
|
||||
24
mantle/signature.circom
Normal file
24
mantle/signature.circom
Normal file
@ -0,0 +1,24 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../ledger/notes.circom";
|
||||
include "../misc/constants.circom";
|
||||
|
||||
template zkSignature(maxInput){
|
||||
signal input secret_keys[maxInput];
|
||||
signal input msg;
|
||||
signal output public_keys[maxInput];
|
||||
|
||||
component pk[maxInput];
|
||||
for(var i =0; i<maxInput; i++){
|
||||
pk[i] = derive_public_key();
|
||||
pk[i].secret_key <== secret_keys[i];
|
||||
public_keys[i] <== pk[i].out;
|
||||
}
|
||||
|
||||
// dummy constraint to avoid unused public input to be erased after compilation optimisation
|
||||
signal dummy;
|
||||
dummy <== msg * msg;
|
||||
}
|
||||
|
||||
component main {public [msg]}= zkSignature(32);
|
||||
80
misc/comparator.circom
Normal file
80
misc/comparator.circom
Normal file
@ -0,0 +1,80 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../circomlib/circuits/bitify.circom";
|
||||
include "../circomlib/circuits/comparators.circom";
|
||||
|
||||
// If a or b isn't guaranteed to be less than p use SafeFullComparator
|
||||
// See https://www.notion.so/nomos-tech/Comparisons-1fd261aa09df81feae1ff3e6612b92a0
|
||||
|
||||
template SafeFullLessThan() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
component bitifier_a = Num2Bits_strict();
|
||||
component bitifier_b = Num2Bits_strict();
|
||||
|
||||
bitifier_a.in <== a;
|
||||
bitifier_b.in <== b;
|
||||
|
||||
component numifier_a = Bits2Num(252);
|
||||
component numifier_b = Bits2Num(252);
|
||||
|
||||
for(var i =0; i<252; i++){
|
||||
numifier_a.in[i] <== bitifier_a.out[i+2];
|
||||
numifier_b.in[i] <== bitifier_b.out[i+2];
|
||||
}
|
||||
|
||||
component A = LessThan(252);
|
||||
A.in[0] <== numifier_b.out;
|
||||
A.in[1] <== numifier_a.out;
|
||||
|
||||
component B = IsEqual();
|
||||
B.in[0] <== numifier_a.out;
|
||||
B.in[1] <== numifier_b.out;
|
||||
|
||||
component C = IsEqual();
|
||||
C.in[0] <== bitifier_a.out[1];
|
||||
C.in[1] <== bitifier_b.out[1];
|
||||
|
||||
component D = IsEqual();
|
||||
D.in[0] <== bitifier_a.out[1];
|
||||
D.in[1] <== 1;
|
||||
|
||||
component E = IsEqual();
|
||||
E.in[0] <== bitifier_a.out[0];
|
||||
E.in[1] <== bitifier_b.out[0];
|
||||
|
||||
component F = IsEqual();
|
||||
F.in[0] <== bitifier_a.out[0];
|
||||
F.in[1] <== 1;
|
||||
|
||||
signal intermediate_results[4];
|
||||
intermediate_results[0] <== (1 - C.out) * (1-D.out);
|
||||
intermediate_results[1] <== (1 - C.out) * (1-E.out);
|
||||
intermediate_results[2] <== intermediate_results[1] * (1- F.out);
|
||||
intermediate_results[3] <== B.out * (intermediate_results[0] + intermediate_results[2]);
|
||||
|
||||
out <== (1 - A.out) * ((1 - B.out) + intermediate_results[3]);
|
||||
}
|
||||
|
||||
// Safely compare two n-bit numbers
|
||||
// Performs range checks on the inputs to avoid overflow. Range is n <= 252
|
||||
template SafeLessThan(n) {
|
||||
assert(n <= 252);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component aInRange = Num2Bits(n);
|
||||
aInRange.in <== in[0];
|
||||
component bInRange = Num2Bits(n);
|
||||
bInRange.in <== in[1];
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[0];
|
||||
lt.in[1] <== in[1];
|
||||
|
||||
out <== lt.out;
|
||||
}
|
||||
67
misc/constants.circom
Normal file
67
misc/constants.circom
Normal file
@ -0,0 +1,67 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../circomlib/circuits/bitify.circom";
|
||||
include "../circomlib/circuits/comparators.circom";
|
||||
|
||||
// int.from_bytes(b"LEAD_V1", byteorder="little") = 13887241025832268
|
||||
template LEAD_V1(){
|
||||
signal output out;
|
||||
out <== 13887241025832268;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"NOMOS_POL_SK_V1", byteorder="little") = 256174383281726064679014503048630094
|
||||
template NOMOS_POL_SK_V1(){
|
||||
signal output out;
|
||||
out <== 256174383281726064679014503048630094;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"NOMOS_NONCE_CONTRIB_V1", byteorder="little") = 18459309511848927313552932915476467038165525790019406
|
||||
template NOMOS_NONCE_CONTRIB_V1(){
|
||||
signal output out;
|
||||
out <== 18459309511848927313552932915476467038165525790019406;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"NOMOS_KDF", byteorder="little") = 1296193216988918402894
|
||||
template NOMOS_KDF(){
|
||||
signal output out;
|
||||
out <== 1296193216988918402894;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"NOMOS_NOTE_ID_V1", byteorder="little") = 65580641562429851895355409762135920462
|
||||
template NOMOS_NOTE_ID_V1(){
|
||||
signal output out;
|
||||
out <== 65580641562429851895355409762135920462;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"SELECTION_RANDOMNESS_V1", byteorder="little") = 4725583332308041445519605499429790922252397838206780755
|
||||
template SELECTION_RANDOMNESS_V1(){
|
||||
signal output out;
|
||||
out <== 4725583332308041445519605499429790922252397838206780755;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"KEY_NULLIFIER_V1", byteorder="little") = 65580642670359595206974785265459610955
|
||||
template KEY_NULLIFIER_V1(){
|
||||
signal output out;
|
||||
out <== 65580642670359595206974785265459610955;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"REWARD_VOUCHER", byteorder="little") = 1668646695034522932676805048878418
|
||||
template REWARD_VOUCHER(){
|
||||
signal output out;
|
||||
out <== 1668646695034522932676805048878418;
|
||||
}
|
||||
|
||||
|
||||
// int.from_bytes(b"VOUCHER_NF", byteorder="little") = 332011368467182873038678
|
||||
template VOUCHER_NF(){
|
||||
signal output out;
|
||||
out <== 332011368467182873038678;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user