mirror of
https://github.com/logos-blockchain/logos-blockchain-pocs.git
synced 2026-01-02 13:13:09 +00:00
commit
3f66449b0c
104
.github/resources/prover/windows.Makefile
vendored
Normal file
104
.github/resources/prover/windows.Makefile
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
###
|
||||
|
||||
#Build targets
|
||||
host:
|
||||
rm -rf build_prover && mkdir build_prover && cd build_prover && \
|
||||
cmake .. \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_INSTALL_PREFIX=../package && \
|
||||
make -j$(nproc) -vvv && make install
|
||||
|
||||
# Copy of the original host target, with specific flags for Windows x86_64 to add patches, missing libraries and
|
||||
# include paths
|
||||
host_windows_x86_64:
|
||||
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="-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
|
||||
|
||||
17
.github/resources/witness-generator/macos.Makefile
vendored
Normal file
17
.github/resources/witness-generator/macos.Makefile
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
CC = g++
|
||||
CFLAGS = -std=c++11 -O3 -I. -I/opt/homebrew/include -include gmp_patch.hpp
|
||||
LDFLAGS = -L/opt/homebrew/lib -lgmp
|
||||
|
||||
DEPS_HPP = circom.hpp calcwit.hpp fr.hpp pol.cpp
|
||||
DEPS_O = main.o calcwit.o fr.o pol.o
|
||||
|
||||
all: pol
|
||||
|
||||
%.o: %.cpp $(DEPS_HPP)
|
||||
$(CC) -Wno-address-of-packed-member -c $< $(CFLAGS) -o $@
|
||||
|
||||
pol: $(DEPS_O)
|
||||
$(CC) -o pol $(DEPS_O) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o pol
|
||||
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
|
||||
17
.github/resources/witness-generator/windows.Makefile
vendored
Normal file
17
.github/resources/witness-generator/windows.Makefile
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
CC = g++
|
||||
CFLAGS = -std=c++11 -O3 -I. -I/include -Duint="unsigned int"
|
||||
LDFLAGS = -L/lib -lgmp -lmman
|
||||
|
||||
DEPS_HPP = circom.hpp calcwit.hpp fr.hpp pol.cpp
|
||||
DEPS_O = main.o calcwit.o fr.o pol.o
|
||||
|
||||
all: pol.exe
|
||||
|
||||
%.o: %.cpp $(DEPS_HPP)
|
||||
$(CC) -Wno-address-of-packed-member -c $< $(CFLAGS) -o $@
|
||||
|
||||
pol.exe: $(DEPS_O)
|
||||
$(CC) -o pol.exe $(DEPS_O) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -f *.o pol.exe
|
||||
538
.github/workflows/build-circuits.yml
vendored
Normal file
538
.github/workflows/build-circuits.yml
vendored
Normal file
@ -0,0 +1,538 @@
|
||||
name: Build Circuits
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags:
|
||||
- "v*.*.*"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Version to release. Must follow the format of 'vX.Y.Z'."
|
||||
required: true
|
||||
pull_request: # For testing purposes
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Configure Environment
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.define-version.outputs.version }}
|
||||
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.
|
||||
VERSION: ${{ github.event.release.tag_name || inputs.version }}
|
||||
run: |
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "No version tag found. Defaulting to commit hash."
|
||||
VERSION=$GITHUB_SHA
|
||||
elif [[ ! "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "VERSION must follow the format of 'vX.Y.Z'. Value: '$VERSION'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Export the version to be used in the following jobs.
|
||||
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
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Initialise Submodules
|
||||
working-directory: repo
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Setup Dependencies
|
||||
working-directory: repo/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: Compile Prover and Verifier
|
||||
working-directory: repo/circom_circuits/rapidsnark
|
||||
run: |
|
||||
./build_gmp.sh host
|
||||
make host
|
||||
|
||||
- name: Generate Witness Generator's C++ Circuit
|
||||
working-directory: repo/circom_circuits/Mantle
|
||||
run: circom --c --r1cs --no_asm --O2 pol.circom
|
||||
|
||||
- name: Compile Witness Generator
|
||||
working-directory: repo/circom_circuits/Mantle/pol_cpp
|
||||
run: make pol
|
||||
|
||||
- name: Bundle Rapidsnark Prover
|
||||
working-directory: repo
|
||||
env:
|
||||
BINARY_NAME: prover
|
||||
BUNDLE_NAME: prover-${{ 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
|
||||
working-directory: repo
|
||||
env:
|
||||
BINARY_NAME: verifier
|
||||
BUNDLE_NAME: verifier-${{ 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 Pol Witness Generator
|
||||
working-directory: repo
|
||||
env:
|
||||
BUNDLE_NAME: pol-${{ env.OS }}-${{ env.ARCH }}
|
||||
WITNESS_GENERATOR_DIR: circom_circuits/Mantle/pol_cpp
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/witness-generator"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${WITNESS_GENERATOR_DIR}"/{pol,pol.dat} "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload Rapidsnark Prover
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: prover-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/prover-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Rapidsnark Verifier
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: verifier-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/verifier-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Pol Witness Generator
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: pol-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/pol-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
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
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Initialise Submodules
|
||||
working-directory: repo
|
||||
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}
|
||||
working-directory: repo
|
||||
run: cp .github/resources/prover/${{ env.OS }}.Makefile circom_circuits/rapidsnark/Makefile
|
||||
|
||||
- name: Replace Prover CMakeLists
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
run: cp .github/resources/prover/${{ env.OS }}.src-CMakeLists.txt circom_circuits/rapidsnark/src/CMakeLists.txt
|
||||
|
||||
- name: Patch Windows mman
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
run: cp .github/resources/prover/${{ env.OS }}.mman_patch.hpp /include/mman_patch.hpp
|
||||
|
||||
- name: Add uio.h headers
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
run: cp .github/resources/prover/${{ env.OS }}.uio.h /include/sys/uio.h
|
||||
|
||||
- name: Replace build_gmp
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
run: cp .github/resources/prover/${{ env.OS }}.build_gmp.sh circom_circuits/rapidsnark/build_gmp.sh
|
||||
|
||||
- name: Compile Prover
|
||||
shell: msys2 {0}
|
||||
working-directory: repo/circom_circuits/rapidsnark
|
||||
run: |
|
||||
./build_gmp.sh host
|
||||
make host_windows_x86_64
|
||||
|
||||
- name: Generate Witness Generator's C++ Circuit
|
||||
working-directory: repo/circom_circuits/Mantle
|
||||
run: circom --c --r1cs --no_asm pol.circom
|
||||
|
||||
- name: Replace Witness Generator Makefile # TODO: Make a fork generate the appropriate Windows Makefile
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
run: cp .github/resources/witness-generator/${{ env.OS }}.Makefile circom_circuits/Mantle/pol_cpp/Makefile
|
||||
|
||||
- name: Compile Witness Generator
|
||||
shell: msys2 {0}
|
||||
working-directory: repo/circom_circuits/Mantle/pol_cpp
|
||||
run: make pol.exe
|
||||
|
||||
- name: Bundle Rapidsnark Prover
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
env:
|
||||
BINARY_NAME: prover
|
||||
BUNDLE_NAME: prover-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
MINGW_BASE_DIR="/${MSYSTEM,,}"
|
||||
MINGW_DLL_DIR="$MINGW_BASE_DIR/bin"
|
||||
cp "$MINGW_DLL_DIR"/{libgcc_s_seh-1.dll,libwinpthread-1.dll,libstdc++-6.dll} "$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}
|
||||
working-directory: repo
|
||||
env:
|
||||
BINARY_NAME: verifier
|
||||
BUNDLE_NAME: verifier-${{ env.OS }}-${{ env.ARCH }}
|
||||
RAPIDSNARK_DIR: circom_circuits/rapidsnark/package
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/${BINARY_NAME}"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
MINGW_BASE_DIR="/${MSYSTEM,,}"
|
||||
MINGW_DLL_DIR="$MINGW_BASE_DIR/bin"
|
||||
cp "$MINGW_DLL_DIR"/{libgcc_s_seh-1.dll,libwinpthread-1.dll,libstdc++-6.dll} "$BUNDLE_DIR/"
|
||||
|
||||
mv "${RAPIDSNARK_DIR}"/bin/${BINARY_NAME}.exe "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Bundle Pol Witness Generator
|
||||
shell: msys2 {0}
|
||||
working-directory: repo
|
||||
env:
|
||||
BUNDLE_NAME: pol-${{ env.OS }}-${{ env.ARCH }}
|
||||
WITNESS_GENERATOR_DIR: circom_circuits/Mantle/pol_cpp
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/witness-generator"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
MINGW_BASE_DIR="/${MSYSTEM,,}"
|
||||
MINGW_DLL_DIR="$MINGW_BASE_DIR/bin"
|
||||
cp "$MINGW_DLL_DIR"/{libgcc_s_seh-1.dll,libwinpthread-1.dll,libstdc++-6.dll,libgmp-10.dll} "$BUNDLE_DIR/"
|
||||
|
||||
mv "${WITNESS_GENERATOR_DIR}/pol" "$BUNDLE_DIR/pol.exe"
|
||||
mv "${WITNESS_GENERATOR_DIR}/pol.dat" "$BUNDLE_DIR/pol.exe.dat"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload Rapidsnark Prover
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: prover-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/prover-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Rapidsnark Verifier
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: verifier-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/verifier-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Pol Witness Generator
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: pol-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/pol-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
build-macos:
|
||||
name: Build MacOS Binaries (Native)
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- setup
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
ARCH: arm64
|
||||
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
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Initialise Submodules
|
||||
working-directory: repo
|
||||
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 cmake nasm m4
|
||||
|
||||
- name: Compile Prover
|
||||
working-directory: repo/circom_circuits/rapidsnark
|
||||
run: |
|
||||
./build_gmp.sh macos_arm64
|
||||
make macos_arm64
|
||||
|
||||
- name: Generate Witness Generator's C++ Circuit
|
||||
working-directory: repo/circom_circuits/Mantle
|
||||
run: circom --c --r1cs --no_asm --O2 pol.circom
|
||||
|
||||
- name: Replace Witness Generator's Makefile # TODO: Make a fork generate the appropriate MacOS Makefile
|
||||
working-directory: repo
|
||||
run: cp .github/resources/witness-generator/${{ env.OS }}.Makefile circom_circuits/Mantle/pol_cpp/Makefile
|
||||
|
||||
- name: Patch MacOS GMP
|
||||
working-directory: repo
|
||||
run: cp .github/resources/witness-generator/${{ env.OS }}.gmp_patch.hpp circom_circuits/Mantle/pol_cpp/gmp_patch.hpp
|
||||
|
||||
- name: Compile Witness Generator
|
||||
working-directory: repo/circom_circuits/Mantle/pol_cpp
|
||||
run: make pol
|
||||
|
||||
- name: Bundle Rapidsnark Prover
|
||||
working-directory: repo
|
||||
env:
|
||||
BINARY_NAME: prover
|
||||
BUNDLE_NAME: prover-${{ 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
|
||||
working-directory: repo
|
||||
env:
|
||||
BINARY_NAME: verifier
|
||||
BUNDLE_NAME: verifier-${{ 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 Pol Witness Generator
|
||||
working-directory: repo
|
||||
env:
|
||||
BUNDLE_NAME: pol-${{ env.OS }}-${{ env.ARCH }}
|
||||
WITNESS_GENERATOR_DIR: circom_circuits/Mantle/pol_cpp
|
||||
run: |
|
||||
BUNDLE_DIR="${BUNDLE_NAME}/witness-generator"
|
||||
mkdir -p "$BUNDLE_DIR"
|
||||
|
||||
mv "${WITNESS_GENERATOR_DIR}"/{pol,pol.dat} "$BUNDLE_DIR/"
|
||||
|
||||
tar -czf "${BUNDLE_NAME}.tar.gz" "${BUNDLE_NAME}"
|
||||
|
||||
- name: Upload Rapidsnark Prover
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: prover-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/prover-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Rapidsnark Verifier
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: verifier-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/verifier-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
- name: Upload Pol Witness Generator
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: pol-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: repo/pol-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
publish-release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
- build-linux
|
||||
- build-windows
|
||||
- build-macos
|
||||
env:
|
||||
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.VERSION }}
|
||||
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: arm64
|
||||
- os: windows
|
||||
arch: x86_64
|
||||
artifact:
|
||||
- prover
|
||||
- verifier
|
||||
- pol
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
UPLOAD_URL: ${{ needs.publish-release.outputs.upload_url }}
|
||||
ARTIFACT_NAME: ${{ matrix.artifact }}-${{ 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
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "circomlib"]
|
||||
path = circom_circuits/circomlib
|
||||
url = https://github.com/iden3/circomlib.git
|
||||
[submodule "circom_circuits/rapidsnark"]
|
||||
path = circom_circuits/rapidsnark
|
||||
url = https://github.com/iden3/rapidsnark
|
||||
|
||||
328
circom_circuits/Blend/generate_inputs_for_poq.py
Normal file
328
circom_circuits/Blend/generate_inputs_for_poq.py
Normal file
@ -0,0 +1,328 @@
|
||||
|
||||
|
||||
|
||||
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 = F(5000)
|
||||
|
||||
t0 = F(0x27b6fe27507ca57ca369280400c79b5d2f58ff94d87cb0fbfc8294eb69eb1ea)
|
||||
t1 = F(0x104bfd09ebdd0a57772289d0973489b62662a4dc6f09da8b4af3c5cfb1dcdd)
|
||||
|
||||
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(randrange(0,p,1))
|
||||
K_two = F(randrange(0,p,1))
|
||||
|
||||
# 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"] = randrange(0,p,1)
|
||||
else:
|
||||
inp["core_root"] = 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
circom_circuits/Blend/poq.circom
Normal file
137
circom_circuits/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.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, pol_ledger_aged, K_part_one, K_part_two ] }
|
||||
= ProofOfQuota(20, 25, 20);
|
||||
@ -1,197 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "montgomeryJubjub.circom";
|
||||
include "jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/comparators.circom";
|
||||
|
||||
template Multiplexor2() {
|
||||
signal input sel;
|
||||
signal input in[2][2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <== (in[1][0] - in[0][0])*sel + in[0][0];
|
||||
out[1] <== (in[1][1] - in[0][1])*sel + in[0][1];
|
||||
}
|
||||
|
||||
template BitElementMulAny() {
|
||||
signal input sel;
|
||||
signal input dblIn[2];
|
||||
signal input addIn[2];
|
||||
signal output dblOut[2];
|
||||
signal output addOut[2];
|
||||
|
||||
component doubler = MontgomeryDouble();
|
||||
component adder = MontgomeryAdd();
|
||||
component selector = Multiplexor2();
|
||||
|
||||
|
||||
sel ==> selector.sel;
|
||||
|
||||
dblIn[0] ==> doubler.in[0];
|
||||
dblIn[1] ==> doubler.in[1];
|
||||
doubler.out[0] ==> adder.in1[0];
|
||||
doubler.out[1] ==> adder.in1[1];
|
||||
addIn[0] ==> adder.in2[0];
|
||||
addIn[1] ==> adder.in2[1];
|
||||
addIn[0] ==> selector.in[0][0];
|
||||
addIn[1] ==> selector.in[0][1];
|
||||
adder.out[0] ==> selector.in[1][0];
|
||||
adder.out[1] ==> selector.in[1][1];
|
||||
|
||||
doubler.out[0] ==> dblOut[0];
|
||||
doubler.out[1] ==> dblOut[1];
|
||||
selector.out[0] ==> addOut[0];
|
||||
selector.out[1] ==> addOut[1];
|
||||
}
|
||||
|
||||
// p is montgomery point
|
||||
// n must be <= 248
|
||||
// returns out in twisted edwards
|
||||
// Double is in montgomery to be linked;
|
||||
|
||||
template SegmentMulAny(n) {
|
||||
signal input e[n];
|
||||
signal input p[2];
|
||||
signal output out[2];
|
||||
signal output dbl[2];
|
||||
|
||||
component bits[n-1];
|
||||
|
||||
component e2m = Edwards2Montgomery();
|
||||
|
||||
p[0] ==> e2m.in[0];
|
||||
p[1] ==> e2m.in[1];
|
||||
|
||||
var i;
|
||||
|
||||
bits[0] = BitElementMulAny();
|
||||
e2m.out[0] ==> bits[0].dblIn[0];
|
||||
e2m.out[1] ==> bits[0].dblIn[1];
|
||||
e2m.out[0] ==> bits[0].addIn[0];
|
||||
e2m.out[1] ==> bits[0].addIn[1];
|
||||
e[1] ==> bits[0].sel;
|
||||
|
||||
for (i=1; i<n-1; i++) {
|
||||
bits[i] = BitElementMulAny();
|
||||
|
||||
bits[i-1].dblOut[0] ==> bits[i].dblIn[0];
|
||||
bits[i-1].dblOut[1] ==> bits[i].dblIn[1];
|
||||
bits[i-1].addOut[0] ==> bits[i].addIn[0];
|
||||
bits[i-1].addOut[1] ==> bits[i].addIn[1];
|
||||
e[i+1] ==> bits[i].sel;
|
||||
}
|
||||
|
||||
bits[n-2].dblOut[0] ==> dbl[0];
|
||||
bits[n-2].dblOut[1] ==> dbl[1];
|
||||
|
||||
component m2e = Montgomery2Edwards();
|
||||
|
||||
bits[n-2].addOut[0] ==> m2e.in[0];
|
||||
bits[n-2].addOut[1] ==> m2e.in[1];
|
||||
|
||||
component eadder = JubjubAdd();
|
||||
|
||||
m2e.out[0] ==> eadder.x1;
|
||||
m2e.out[1] ==> eadder.y1;
|
||||
-p[0] ==> eadder.x2;
|
||||
p[1] ==> eadder.y2;
|
||||
|
||||
component lastSel = Multiplexor2();
|
||||
|
||||
e[0] ==> lastSel.sel;
|
||||
eadder.xout ==> lastSel.in[0][0];
|
||||
eadder.yout ==> lastSel.in[0][1];
|
||||
m2e.out[0] ==> lastSel.in[1][0];
|
||||
m2e.out[1] ==> lastSel.in[1][1];
|
||||
|
||||
lastSel.out[0] ==> out[0];
|
||||
lastSel.out[1] ==> out[1];
|
||||
}
|
||||
|
||||
// This function assumes that p is in the subgroup and it is different to 0
|
||||
|
||||
template EscalarMulAny(n) {
|
||||
signal input e[n]; // Input in binary format
|
||||
signal input p[2]; // Point (Twisted format)
|
||||
signal output out[2]; // Point (Twisted format)
|
||||
|
||||
var nsegments = (n-1)\148 +1;
|
||||
var nlastsegment = n - (nsegments-1)*148;
|
||||
|
||||
component segments[nsegments];
|
||||
component doublers[nsegments-1];
|
||||
component m2e[nsegments-1];
|
||||
component adders[nsegments-1];
|
||||
component zeropoint = IsZero();
|
||||
zeropoint.in <== p[0];
|
||||
|
||||
var s;
|
||||
var i;
|
||||
var nseg;
|
||||
|
||||
for (s=0; s<nsegments; s++) {
|
||||
|
||||
nseg = (s < nsegments-1) ? 148 : nlastsegment;
|
||||
|
||||
segments[s] = SegmentMulAny(nseg);
|
||||
|
||||
for (i=0; i<nseg; i++) {
|
||||
e[s*148+i] ==> segments[s].e[i];
|
||||
}
|
||||
|
||||
if (s==0) {
|
||||
// force G8 point if input point is zero
|
||||
segments[s].p[0] <== p[0] + (0x11dafe5d23e1218086a365b99fbf3d3be72f6afd7d1f72623e6b071492d1122b - p[0])*zeropoint.out;
|
||||
segments[s].p[1] <== p[1] + (0x1d523cf1ddab1a1793132e78c866c0c33e26ba5cc220fed7cc3f870e59d292aa - p[1])*zeropoint.out;
|
||||
} else {
|
||||
doublers[s-1] = MontgomeryDouble();
|
||||
m2e[s-1] = Montgomery2Edwards();
|
||||
adders[s-1] = JubjubAdd();
|
||||
|
||||
segments[s-1].dbl[0] ==> doublers[s-1].in[0];
|
||||
segments[s-1].dbl[1] ==> doublers[s-1].in[1];
|
||||
|
||||
doublers[s-1].out[0] ==> m2e[s-1].in[0];
|
||||
doublers[s-1].out[1] ==> m2e[s-1].in[1];
|
||||
|
||||
m2e[s-1].out[0] ==> segments[s].p[0];
|
||||
m2e[s-1].out[1] ==> segments[s].p[1];
|
||||
|
||||
if (s==1) {
|
||||
segments[s-1].out[0] ==> adders[s-1].x1;
|
||||
segments[s-1].out[1] ==> adders[s-1].y1;
|
||||
} else {
|
||||
adders[s-2].xout ==> adders[s-1].x1;
|
||||
adders[s-2].yout ==> adders[s-1].y1;
|
||||
}
|
||||
segments[s].out[0] ==> adders[s-1].x2;
|
||||
segments[s].out[1] ==> adders[s-1].y2;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsegments == 1) {
|
||||
segments[0].out[0]*(1-zeropoint.out) ==> out[0];
|
||||
segments[0].out[1]+(1-segments[0].out[1])*zeropoint.out ==> out[1];
|
||||
} else {
|
||||
adders[nsegments-2].xout*(1-zeropoint.out) ==> out[0];
|
||||
adders[nsegments-2].yout+(1-adders[nsegments-2].yout)*zeropoint.out ==> out[1];
|
||||
}
|
||||
}
|
||||
@ -1,63 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
pragma circom 2.1.9;
|
||||
|
||||
template JubjubAdd() {
|
||||
signal input x1;
|
||||
signal input y1;
|
||||
signal input x2;
|
||||
signal input y2;
|
||||
signal output xout;
|
||||
signal output yout;
|
||||
|
||||
signal beta;
|
||||
signal gamma;
|
||||
signal delta;
|
||||
signal tau;
|
||||
|
||||
var a = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000;
|
||||
var d = 0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1;
|
||||
|
||||
beta <== x1*y2;
|
||||
gamma <== y1*x2;
|
||||
delta <== (-a*x1+y1)*(x2 + y2);
|
||||
tau <== beta * gamma;
|
||||
|
||||
xout <-- (beta + gamma) / (1+ d*tau);
|
||||
(1+ d*tau) * xout === (beta + gamma);
|
||||
|
||||
yout <-- (delta + a*beta - gamma) / (1-d*tau);
|
||||
(1-d*tau)*yout === (delta + a*beta - gamma);
|
||||
}
|
||||
|
||||
template JubjubDbl() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
signal output xout;
|
||||
signal output yout;
|
||||
|
||||
component adder = JubjubAdd();
|
||||
adder.x1 <== x;
|
||||
adder.y1 <== y;
|
||||
adder.x2 <== x;
|
||||
adder.y2 <== y;
|
||||
|
||||
adder.xout ==> xout;
|
||||
adder.yout ==> yout;
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Source: https://en.wikipedia.org/wiki/Montgomery_curve
|
||||
|
||||
1 + y 1 + y
|
||||
[u, v] = [ ------- , ---------- ]
|
||||
1 - y (1 - y)x
|
||||
|
||||
*/
|
||||
pragma circom 2.0.0;
|
||||
|
||||
template Edwards2Montgomery() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <-- (1 + in[1]) / (1 - in[1]);
|
||||
out[1] <-- out[0] / in[0];
|
||||
|
||||
|
||||
out[0] * (1-in[1]) === (1 + in[1]);
|
||||
out[1] * in[0] === out[0];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
u u - 1
|
||||
[x, y] = [ ---, ------- ]
|
||||
v u + 1
|
||||
|
||||
*/
|
||||
template Montgomery2Edwards() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <-- in[0] / in[1];
|
||||
out[1] <-- (in[0] - 1) / (in[0] + 1);
|
||||
|
||||
out[0] * in[1] === in[0];
|
||||
out[1] * (in[0] + 1) === in[0] - 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
x2 - x1
|
||||
lamda = ---------
|
||||
y2 - y1
|
||||
|
||||
x3 + A + x1 + x2
|
||||
x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------
|
||||
B
|
||||
|
||||
y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 =>
|
||||
|
||||
|
||||
=> y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 =>
|
||||
|
||||
=> y3 = lamda * ( x1 - x3 ) - y1
|
||||
|
||||
----------
|
||||
|
||||
y2 - y1
|
||||
lamda = ---------
|
||||
x2 - x1
|
||||
|
||||
x3 = B * lamda^2 - A - x1 -x2
|
||||
|
||||
y3 = lamda * ( x1 - x3 ) - y1
|
||||
|
||||
*/
|
||||
|
||||
template MontgomeryAdd() {
|
||||
signal input in1[2];
|
||||
signal input in2[2];
|
||||
signal output out[2];
|
||||
|
||||
var a = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000;
|
||||
var d = 0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1;
|
||||
|
||||
var A = (2 * (a + d)) / (a - d);
|
||||
var B = 4 / (a - d);
|
||||
|
||||
signal lamda;
|
||||
|
||||
lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]);
|
||||
lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]);
|
||||
|
||||
out[0] <== B*lamda*lamda - A - in1[0] -in2[0];
|
||||
out[1] <== lamda * (in1[0] - out[0]) - in1[1];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
x1_2 = x1*x1
|
||||
|
||||
3*x1_2 + 2*A*x1 + 1
|
||||
lamda = ---------------------
|
||||
2*B*y1
|
||||
|
||||
x3 = B * lamda^2 - A - x1 -x1
|
||||
|
||||
y3 = lamda * ( x1 - x3 ) - y1
|
||||
|
||||
*/
|
||||
template MontgomeryDouble() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
var a = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000;
|
||||
var d = 0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1;
|
||||
|
||||
var A = (2 * (a + d)) / (a - d);
|
||||
var B = 4 / (a - d);
|
||||
|
||||
signal lamda;
|
||||
signal x1_2;
|
||||
|
||||
x1_2 <== in[0] * in[0];
|
||||
|
||||
lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]);
|
||||
lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 );
|
||||
|
||||
out[0] <== B*lamda*lamda - A - 2*in[0];
|
||||
out[1] <== lamda * (in[0] - out[0]) - in[1];
|
||||
}
|
||||
305
circom_circuits/Mantle/generate_inputs_for_pol.py
Executable file
305
circom_circuits/Mantle/generate_inputs_for_pol.py
Executable file
@ -0,0 +1,305 @@
|
||||
#!/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 = F(0x27b6fe27507ca57ca369280400c79b5d2f58ff94d87cb0fbfc8294eb69eb1ea)
|
||||
t1 = F(0x104bfd09ebdd0a57772289d0973489b62662a4dc6f09da8b4af3c5cfb1dcdd)
|
||||
|
||||
|
||||
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
circom_circuits/Mantle/generate_inputs_for_proof_of_claim.py
Executable file
238
circom_circuits/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
circom_circuits/Mantle/generate_inputs_for_signature.py
Executable file
232
circom_circuits/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")
|
||||
250
circom_circuits/Mantle/pol.circom
Normal file
250
circom_circuits/Mantle/pol.circom
Normal file
@ -0,0 +1,250 @@
|
||||
//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;
|
||||
}
|
||||
|
||||
|
||||
component main {public [sl,epoch_nonce,t0,t1,ledger_aged,ledger_latest,P_lead_part_one,P_lead_part_two]}= proof_of_leadership(25);
|
||||
74
circom_circuits/Mantle/proof_of_claim.circom
Normal file
74
circom_circuits/Mantle/proof_of_claim.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();
|
||||
24
circom_circuits/Mantle/signature.circom
Normal file
24
circom_circuits/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);
|
||||
@ -1,184 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "anemoi_Jubjub_16_to_1_constants.circom";
|
||||
|
||||
template ark_layer_16_to_1(round_number) {
|
||||
assert(round_number < 10);
|
||||
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
var C[10][8] = C_16_to_1();
|
||||
var D[10][8] = D_16_to_1();
|
||||
|
||||
for(var i=0; i<8; i++){
|
||||
out[i] <== in[i] + C[round_number][i];
|
||||
out[8+i] <== in[8+i] + D[round_number][i];
|
||||
}
|
||||
}
|
||||
|
||||
template pow_alpha_16_to_1() { // ALPHA = 5
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2 * in2;
|
||||
out <== in4 * in;
|
||||
}
|
||||
|
||||
template mds_layer_16_to_1() {
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
/* M_x= [1 2 3 5 7 8 8 9]
|
||||
[9 1 2 3 5 7 8 8]
|
||||
[8 9 1 2 3 5 7 8]
|
||||
[8 8 9 1 2 3 5 7]
|
||||
[7 8 8 9 1 2 3 5]
|
||||
[5 7 8 8 9 1 2 3]
|
||||
[3 5 7 8 8 9 1 2]
|
||||
[2 3 5 7 8 8 9 1] */
|
||||
|
||||
signal x[8];
|
||||
signal y[8];
|
||||
|
||||
x[0] <== 1*in[0] + 2*in[1] + 3*in[2] + 5*in[3] + 7*in[4] + 8*in[5] + 8*in[6] + 9*in[7];
|
||||
x[1] <== 9*in[0] + 1*in[1] + 2*in[2] + 3*in[3] + 5*in[4] + 7*in[5] + 8*in[6] + 8*in[7];
|
||||
x[2] <== 8*in[0] + 9*in[1] + 1*in[2] + 2*in[3] + 3*in[4] + 5*in[5] + 7*in[6] + 8*in[7];
|
||||
x[3] <== 8*in[0] + 8*in[1] + 9*in[2] + 1*in[3] + 2*in[4] + 3*in[5] + 5*in[6] + 7*in[7];
|
||||
x[4] <== 7*in[0] + 8*in[1] + 8*in[2] + 9*in[3] + 1*in[4] + 2*in[5] + 3*in[6] + 5*in[7];
|
||||
x[5] <== 5*in[0] + 7*in[1] + 8*in[2] + 8*in[3] + 9*in[4] + 1*in[5] + 2*in[6] + 3*in[7];
|
||||
x[6] <== 3*in[0] + 5*in[1] + 7*in[2] + 8*in[3] + 8*in[4] + 9*in[5] + 1*in[6] + 2*in[7];
|
||||
x[7] <== 2*in[0] + 3*in[1] + 5*in[2] + 7*in[3] + 8*in[4] + 8*in[5] + 9*in[6] + 1*in[7];
|
||||
|
||||
y[0] <== 1*in[9] + 2*in[10] + 3*in[11] + 5*in[12] + 7*in[13] + 8*in[14] + 8*in[15] + 9*in[8];
|
||||
y[1] <== 9*in[9] + 1*in[10] + 2*in[11] + 3*in[12] + 5*in[13] + 7*in[14] + 8*in[15] + 8*in[8];
|
||||
y[2] <== 8*in[9] + 9*in[10] + 1*in[11] + 2*in[12] + 3*in[13] + 5*in[14] + 7*in[15] + 8*in[8];
|
||||
y[3] <== 8*in[9] + 8*in[10] + 9*in[11] + 1*in[12] + 2*in[13] + 3*in[14] + 5*in[15] + 7*in[8];
|
||||
y[4] <== 7*in[9] + 8*in[10] + 8*in[11] + 9*in[12] + 1*in[13] + 2*in[14] + 3*in[15] + 5*in[8];
|
||||
y[5] <== 5*in[9] + 7*in[10] + 8*in[11] + 8*in[12] + 9*in[13] + 1*in[14] + 2*in[15] + 3*in[8];
|
||||
y[6] <== 3*in[9] + 5*in[10] + 7*in[11] + 8*in[12] + 8*in[13] + 9*in[14] + 1*in[15] + 2*in[8];
|
||||
y[7] <== 2*in[9] + 3*in[10] + 5*in[11] + 7*in[12] + 8*in[13] + 8*in[14] + 9*in[15] + 1*in[8];
|
||||
|
||||
for(var i=0; i<8; i++){
|
||||
out[8+i] <== x[i] + y[i];
|
||||
out[i] <== x[i] + out[8+i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template s_box_16_to_1() {
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
|
||||
//Computation using open Flystel
|
||||
var x[8];
|
||||
var y[8];
|
||||
|
||||
for(var i=0; i<8; i++){
|
||||
x[i] = in[i];
|
||||
y[i] = in[8+i];
|
||||
x[i] = x[i] - 7 * (y[i]**2);
|
||||
y[i] = y[i] - (x[i]**20974350070050476191779096203274386335076221000211055129041463479975432473805); // 1/ALPHA
|
||||
x[i] = x[i] + 7 * (y[i]**2) + 14981678621464625851270783002338847382197300714436467949315331057125308909861; // DELTA
|
||||
out[i] <-- x[i];
|
||||
out[8+i] <-- y[i];
|
||||
}
|
||||
|
||||
//Verification using closed Flystel
|
||||
component pow[8];
|
||||
signal y2[8];
|
||||
signal v2[8];
|
||||
|
||||
for(var i=0; i<8; i++){
|
||||
pow[i] = pow_alpha_16_to_1();
|
||||
pow[i].in <== in[8+i] - out[8+i];
|
||||
y2[i] <== in[8+i]*in[8+i];
|
||||
v2[i] <== out[8+i]*out[8+i];
|
||||
in[i] === pow[i].out + 7 * y2[i];
|
||||
out[i] === pow[i].out + 7 * v2[i] + 14981678621464625851270783002338847382197300714436467949315331057125308909861;// DELTA
|
||||
}
|
||||
}
|
||||
|
||||
template round_16_to_1(round_number) {
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
component cst = ark_layer_16_to_1(round_number);
|
||||
component mds = mds_layer_16_to_1();
|
||||
component sbox = s_box_16_to_1();
|
||||
|
||||
for(var i=0; i<16; i++){
|
||||
cst.in[i] <== in[i];
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
mds.in[i] <== cst.out[i];
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
sbox.in[i] <== mds.out[i];
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
out[i] <== sbox.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template permutation_16_to_1(){
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
component rounds[10];
|
||||
component mds = mds_layer_16_to_1();
|
||||
|
||||
for(var i = 0; i<10; i++){ //10 rounds
|
||||
rounds[i] = round_16_to_1(i);
|
||||
if(i==0){
|
||||
for(var j=0; j<16; j++){
|
||||
rounds[i].in[j] <== in[j];
|
||||
}
|
||||
} else {
|
||||
for(var j=0; j<16; j++){
|
||||
rounds[i].in[j] <== rounds[i-1].out[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
mds.in[i] <== rounds[9].out[i];
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
out[i] <== mds.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template hash_16_to_1(){
|
||||
signal input in[16];
|
||||
signal output out;
|
||||
|
||||
component perm = permutation_16_to_1();
|
||||
for(var i=0; i<16; i++){
|
||||
perm.in[i] <== in[i];
|
||||
}
|
||||
|
||||
out <== in[0] + perm.out[0] +
|
||||
in[1] + perm.out[1] +
|
||||
in[2] + perm.out[2] +
|
||||
in[3] + perm.out[3] +
|
||||
in[4] + perm.out[4] +
|
||||
in[5] + perm.out[5] +
|
||||
in[6] + perm.out[6] +
|
||||
in[7] + perm.out[7] +
|
||||
in[8] + perm.out[8] +
|
||||
in[9] + perm.out[9] +
|
||||
in[10] + perm.out[10] +
|
||||
in[11] + perm.out[11] +
|
||||
in[12] + perm.out[12] +
|
||||
in[13] + perm.out[13] +
|
||||
in[14] + perm.out[14] +
|
||||
in[15] + perm.out[15];
|
||||
}
|
||||
|
||||
//component main = hash_16_to_1();
|
||||
@ -1,122 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "anemoi_Jubjub_2_to_1_constants.circom";
|
||||
|
||||
template ark_layer_2_to_1(round_number) {
|
||||
assert(round_number < 21);
|
||||
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
var C[21] = C_2_to_1();
|
||||
var D[21] = D_2_to_1();
|
||||
|
||||
out[0] <== in[0] + C[round_number];
|
||||
out[1] <== in[1] + D[round_number];
|
||||
}
|
||||
|
||||
template pow_alpha_2_to_1() { // ALPHA = 5
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2 * in2;
|
||||
out <== in4 * in;
|
||||
}
|
||||
|
||||
template mds_layer_2_to_1() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
out[1] <== in[1] + in[0];
|
||||
out[0] <== in[0] + out[1];
|
||||
}
|
||||
|
||||
template s_box_2_to_1() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
|
||||
//Calculation using open Flystel
|
||||
var x;
|
||||
var y;
|
||||
x = in[0];
|
||||
y = in[1];
|
||||
|
||||
x = x - 7 * (y**2);
|
||||
y = y - (x**20974350070050476191779096203274386335076221000211055129041463479975432473805); // 1/ALPHA
|
||||
x = x + 7 * (y**2) + 14981678621464625851270783002338847382197300714436467949315331057125308909861; //DELTA
|
||||
out[0] <-- x;
|
||||
out[1] <-- y;
|
||||
|
||||
|
||||
//Verification using closed Flystel
|
||||
|
||||
component pow = pow_alpha_2_to_1();
|
||||
pow.in <== in[1] - out[1];
|
||||
|
||||
signal y2;
|
||||
signal v2;
|
||||
y2 <== in[1]*in[1];
|
||||
v2 <==out[1]*out[1];
|
||||
in[0] === pow.out + 7 * y2;
|
||||
out[0] === pow.out + 7 * v2 + 14981678621464625851270783002338847382197300714436467949315331057125308909861;// DELTA
|
||||
}
|
||||
|
||||
template round_2_to_1(round_number) {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
component cst = ark_layer_2_to_1(round_number);
|
||||
component mds = mds_layer_2_to_1();
|
||||
component sbox = s_box_2_to_1();
|
||||
|
||||
cst.in[0] <== in[0];
|
||||
cst.in[1] <== in[1];
|
||||
mds.in[0] <== cst.out[0];
|
||||
mds.in[1] <== cst.out[1];
|
||||
sbox.in[0] <== mds.out[0];
|
||||
sbox.in[1] <== mds.out[1];
|
||||
out[0] <== sbox.out[0];
|
||||
out[1] <== sbox.out[1];
|
||||
}
|
||||
|
||||
template permutation_2_to_1(){
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
component rounds[21];
|
||||
component mds = mds_layer_2_to_1();
|
||||
|
||||
for(var i = 0; i<21; i++){ //21 rounds
|
||||
rounds[i] = round_2_to_1(i);
|
||||
if(i==0){
|
||||
rounds[i].in[0] <== in[0];
|
||||
rounds[i].in[1] <== in[1];
|
||||
} else {
|
||||
rounds[i].in[0] <== rounds[i-1].out[0];
|
||||
rounds[i].in[1] <== rounds[i-1].out[1];
|
||||
}
|
||||
}
|
||||
mds.in[0] <== rounds[20].out[0];
|
||||
mds.in[1] <== rounds[20].out[1];
|
||||
out[0] <== mds.out[0];
|
||||
out[1] <== mds.out[1];
|
||||
}
|
||||
|
||||
template hash_2_to_1(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component perm = permutation_2_to_1();
|
||||
perm.in[0] <== in[0];
|
||||
perm.in[1] <== in[1];
|
||||
|
||||
out <== in[0] + perm.out[0] + in[1] + perm.out[1];
|
||||
}
|
||||
|
||||
//component main = hash_2_to_1();
|
||||
@ -1,179 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "anemoi_Jubjub_4_to_1_constants.circom";
|
||||
|
||||
template ark_layer_4_to_1(round_number) {
|
||||
assert(round_number < 14);
|
||||
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
var C[14][2] = C_4_to_1();
|
||||
var D[14][2] = D_4_to_1();
|
||||
|
||||
out[0] <== in[0] + C[round_number][0];
|
||||
out[1] <== in[1] + C[round_number][1];
|
||||
out[2] <== in[2] + D[round_number][0];
|
||||
out[3] <== in[3] + D[round_number][1];
|
||||
}
|
||||
|
||||
template pow_alpha_4_to_1() { // ALPHA = 5
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2 * in2;
|
||||
out <== in4 * in;
|
||||
}
|
||||
|
||||
template mds_layer_4_to_1() {
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
signal x0;
|
||||
signal x1;
|
||||
signal y0;
|
||||
signal y1;
|
||||
|
||||
x0 <== in[0] + 7*in[1];
|
||||
x1 <== 7*in[0] + 50*in[1];
|
||||
|
||||
y0 <== in[3] + 7*in[2];
|
||||
y1 <== 7*in[3] + 50*in[2];
|
||||
|
||||
out[2] <== y0 + x0;
|
||||
out[3] <== y1 + x1;
|
||||
out[0] <== x0 + out[2];
|
||||
out[1] <== x1 + out[3];
|
||||
}
|
||||
|
||||
|
||||
template s_box_4_to_1() {
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
|
||||
//Calculation using open Flystel
|
||||
var x0;
|
||||
var y0;
|
||||
x0 = in[0];
|
||||
y0 = in[2];
|
||||
|
||||
x0 = x0 - 7 * (y0**2);
|
||||
y0 = y0 - (x0**20974350070050476191779096203274386335076221000211055129041463479975432473805); // 1/ALPHA
|
||||
x0 = x0 + 7 * (y0**2) + 14981678621464625851270783002338847382197300714436467949315331057125308909861; //DELTA
|
||||
|
||||
var x1;
|
||||
var y1;
|
||||
x1 = in[1];
|
||||
y1 = in[3];
|
||||
|
||||
x1 = x1 - 7 * (y1**2);
|
||||
y1 = y1 - (x1**20974350070050476191779096203274386335076221000211055129041463479975432473805); // 1/ALPHA
|
||||
x1 = x1 + 7 * (y1**2) + 14981678621464625851270783002338847382197300714436467949315331057125308909861; //DELTA
|
||||
|
||||
out[0] <-- x0;
|
||||
out[1] <-- x1;
|
||||
out[2] <-- y0;
|
||||
out[3] <-- y1;
|
||||
|
||||
|
||||
//Verification using closed Flystel
|
||||
|
||||
component pow[2];
|
||||
pow[0] = pow_alpha_4_to_1();
|
||||
pow[1] = pow_alpha_4_to_1();
|
||||
|
||||
|
||||
pow[0].in <== in[2] - out[2];
|
||||
signal y0_2;
|
||||
signal v0_2;
|
||||
y0_2 <== in[2]*in[2];
|
||||
v0_2 <==out[2]*out[2];
|
||||
in[0] === pow[0].out + 7 * y0_2;
|
||||
out[0] === pow[0].out + 7 * v0_2 + 14981678621464625851270783002338847382197300714436467949315331057125308909861;// DELTA
|
||||
|
||||
pow[1].in <== in[3] - out[3];
|
||||
signal y1_2;
|
||||
signal v1_2;
|
||||
y1_2 <== in[3]*in[3];
|
||||
v1_2 <==out[3]*out[3];
|
||||
in[1] === pow[1].out + 7 * y1_2;
|
||||
out[1] === pow[1].out + 7 * v1_2 + 14981678621464625851270783002338847382197300714436467949315331057125308909861;// DELTA
|
||||
}
|
||||
|
||||
template round_4_to_1(round_number) {
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
component cst = ark_layer_4_to_1(round_number);
|
||||
component mds = mds_layer_4_to_1();
|
||||
component sbox = s_box_4_to_1();
|
||||
|
||||
cst.in[0] <== in[0];
|
||||
cst.in[1] <== in[1];
|
||||
cst.in[2] <== in[2];
|
||||
cst.in[3] <== in[3];
|
||||
mds.in[0] <== cst.out[0];
|
||||
mds.in[1] <== cst.out[1];
|
||||
mds.in[2] <== cst.out[2];
|
||||
mds.in[3] <== cst.out[3];
|
||||
sbox.in[0] <== mds.out[0];
|
||||
sbox.in[1] <== mds.out[1];
|
||||
sbox.in[2] <== mds.out[2];
|
||||
sbox.in[3] <== mds.out[3];
|
||||
out[0] <== sbox.out[0];
|
||||
out[1] <== sbox.out[1];
|
||||
out[2] <== sbox.out[2];
|
||||
out[3] <== sbox.out[3];
|
||||
}
|
||||
|
||||
template permutation_4_to_1(){
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
component rounds[14];
|
||||
component mds = mds_layer_4_to_1();
|
||||
|
||||
for(var i = 0; i<14; i++){ //14 rounds
|
||||
rounds[i] = round_4_to_1(i);
|
||||
if(i==0){
|
||||
rounds[i].in[0] <== in[0];
|
||||
rounds[i].in[1] <== in[1];
|
||||
rounds[i].in[2] <== in[2];
|
||||
rounds[i].in[3] <== in[3];
|
||||
} else {
|
||||
rounds[i].in[0] <== rounds[i-1].out[0];
|
||||
rounds[i].in[1] <== rounds[i-1].out[1];
|
||||
rounds[i].in[2] <== rounds[i-1].out[2];
|
||||
rounds[i].in[3] <== rounds[i-1].out[3];
|
||||
}
|
||||
}
|
||||
mds.in[0] <== rounds[13].out[0];
|
||||
mds.in[1] <== rounds[13].out[1];
|
||||
mds.in[2] <== rounds[13].out[2];
|
||||
mds.in[3] <== rounds[13].out[3];
|
||||
out[0] <== mds.out[0];
|
||||
out[1] <== mds.out[1];
|
||||
out[2] <== mds.out[2];
|
||||
out[3] <== mds.out[3];
|
||||
}
|
||||
|
||||
template hash_4_to_1(){
|
||||
signal input in[4];
|
||||
signal output out;
|
||||
|
||||
component perm = permutation_4_to_1();
|
||||
perm.in[0] <== in[0];
|
||||
perm.in[1] <== in[1];
|
||||
perm.in[2] <== in[2];
|
||||
perm.in[3] <== in[3];
|
||||
|
||||
out <== in[0] + perm.out[0] + in[1] + perm.out[1] + in[2] + perm.out[2] + in[3] + perm.out[3];
|
||||
}
|
||||
|
||||
//component main = hash_4_to_1();
|
||||
@ -1,174 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
function C_16_to_1() {
|
||||
return
|
||||
[
|
||||
[39,
|
||||
17756515227822460609684409997111995494590448775258437999344446424780281143353,
|
||||
10188916128123599964772546147951904500865009616764646948187915341627970346879,
|
||||
3814237141406755457246679946340702245820791055503616462386588886553626328449,
|
||||
31231358838611540266091127386940316382485316827738464579249222989762089961618,
|
||||
3726010289701932654130304682574596267996890432970838266711107863585526844332,
|
||||
36992578177313978374320714629037014712724552282717071185860782184820525992055,
|
||||
6539662723010541897260760345121608837413747021964775102659796495628351576700],
|
||||
[41362478282768062297187132445775312675360473883834860695283235286481594490621,
|
||||
3384073892082712848969991795331397937188893616190315628722966662742467187281,
|
||||
38536464596998108028197905645250196649287447208374169339784649587982292038621,
|
||||
37592197675289757358471908199906415982484124338112374453435292524131427342810,
|
||||
23880328728725835218995126249367316438768592574548525705412373412647097582882,
|
||||
48825064577758348008118486787590853038041005302054740877940928369291358302191,
|
||||
50534173420081783859714292066423124353911378857266355124747257390448683204724,
|
||||
7428946804745276726594228607058422733621008211707460976374155647815125702793],
|
||||
[9548818195234740988996233204400874453525674173109474205108603996010297049928,
|
||||
51311880822158488881090781617710146800056386303122657365679608608648067582435,
|
||||
24596965950552905296088269899880882549715354660832391374009234980535928382152,
|
||||
34036826250287807194659359129722586818079652442547178531030410684351456041117,
|
||||
47245638746867242507412562212796342461134942817161752237394648503282879275118,
|
||||
31300595906266724771648800100316060631685700019604649908550024867487861705279,
|
||||
3785144237087232802472944225009874259820952161256157218342463192641540401693,
|
||||
13192072039732854032991114991329331830093509159172499125522354840599160152710],
|
||||
[25365440569177822667580105183435418073995888230868180942004497015015045856900,
|
||||
29347609441914902330741511702270026847909178228078752565372729158237774700914,
|
||||
14356478667385969079309349540394948109414829921001045845599553435706989367858,
|
||||
9488013611624811735432450930006811652991761655550510302915118428283918068143,
|
||||
46788925259457988525082226160565541608877312582477767975013905645120335169226,
|
||||
39167900530643229840202791109535532972977251341471019870612379478843295475401,
|
||||
35468869056801697991539514623685427699753784556397696975236370718172619478088,
|
||||
10386758415207822166675671630819234802877311049149240741713298889822859300210],
|
||||
[34023498397393406644117994167986720327178154686105264833093891093045919619309,
|
||||
2339620320400167830454536231899316133967303509954474267430948538955691907104,
|
||||
12136748919666286297989154404429099226154686992028401568133058190732008277996,
|
||||
19442569822772655270268482835742480365499256802520510905846953360427433130058,
|
||||
6121842489566508888444793919988648467487285035515564826894797322329857604679,
|
||||
52423305139993282549959548255411402052505266722715464547641713196825757370045,
|
||||
721115880708783722056278375691123676170968994983418732948150001331611213553,
|
||||
28368777671879812853105774722579268517023359292257929653599900440020077784493],
|
||||
[38816051319719761886041858113129205506758421478656182868737326994635468402951,
|
||||
27338042530319738113354246208426108832239651080023276643867223794985578055610,
|
||||
15580674179713644540398409523441814073810768449493940562136422009899312699155,
|
||||
4362660876979205605782410963041525734654031488177761934879852229226211686053,
|
||||
11650586156654079013116836535888803264128748996614961532114710040258230535152,
|
||||
19531964257180260867876509318520389540889883401661971174170106848135773712126,
|
||||
28219700779483915272028450015085470411949576744039967576016029120273878374251,
|
||||
33474277480452546775130924043517012470949538154685955521260479155699441559340],
|
||||
[35167418087531820804128377095512663922179887277669504047069913414630376083753,
|
||||
42192983528513372869128514327443204912824559545179630597589572656156258515752,
|
||||
47389212411441573266379092392931599970417884729397156841216318364858334633325,
|
||||
41487656259632727393098274178738763934249662924287956242704596746920012242443,
|
||||
47585046162349898019384381324380934361400616741262019467964248889992556789636,
|
||||
22864477306086472394102077909444955034170624450796904926669386049666664492257,
|
||||
13351050514115985199153581050320477287713057625178307041078042677800880924875,
|
||||
37405300160039662564807777381564989963058089105400420537288945543199341594301],
|
||||
[25885868839756469722325652387535232478219821850603640827385444642154834700231,
|
||||
42721818980548514490325424436763032046927347769153393863616095871384405840432,
|
||||
5855288403637341107158034195599277569854359593529752399086836976954392351035,
|
||||
18845851722124019325834426094831743068408557621685658713002749358354699910772,
|
||||
33256528590007803378062158842587476459976080810702643409997408348306082386089,
|
||||
2234591446681396008493892860306849390171100567645872660203494363121541667798,
|
||||
194686086885408743916631695867994306362987352657004869135407425114760399927,
|
||||
28761022534147935351682915336446217569572759443228321225221961720692449395484],
|
||||
[8867588811641202981080659274007552529205713737251862066053445622305818871963,
|
||||
23473499332437056484066006746048591864129988909190267521144125882222313735740,
|
||||
5696063807157149622355481994320806474692190935543821893362808351446578125354,
|
||||
48558031599255072862103809681060565464555437399403822458902024251997890071747,
|
||||
29805490370918962312941798594103721605222271424104745148638516522088829641991,
|
||||
37489036434356676843050473824100415300808075220521554146913930229334867812254,
|
||||
11631357050894820069054650807562155039191303868752185889040197345022629525927,
|
||||
24660767228992591228910666543569781024799661249145320635218341313794706416082],
|
||||
[36439756010140137556111047750162544185710881404522379792044818039722752946048,
|
||||
16497366583607480604161417644040292299204496829635795525393416854929276060989,
|
||||
31479323495970113713816467604460499675889579912370034974841212556442942086146,
|
||||
52327065242455117582590188333899352706031813782154293138553490341266149456684,
|
||||
22462223600300108924276123720518708580622354327562062947406284488847554180931,
|
||||
40996278729170725855966064159584167091102415184996744640950022676164065046834,
|
||||
19430817579416357934148820670939901668848861606295052060308554899051486801548,
|
||||
12483379002100433076591219143638049458199676871775181258981956241115974881163]
|
||||
];
|
||||
}
|
||||
|
||||
function D_16_to_1() {
|
||||
return
|
||||
[
|
||||
[14981678621464625851270783002338847382197300714436467949315331057125308909900,
|
||||
48720959343719104324739338388885839802998711550637402773896395605948383052052,
|
||||
11709610427641952476226704950218052763560489079301307464225164120801969364960,
|
||||
3188799073106888901912065951229864304299742047220134499402570163601813730969,
|
||||
35055566170683830204685883433867693478135114051401583710007741398997412970579,
|
||||
41969389849183863090802087476567191363990360356945841340095187311995419576515,
|
||||
7556226394164164334481570938023506204252451033715203682883249970224239802922,
|
||||
17176882240248932567902590122153974429675966351354956648777145117980813990398],
|
||||
[28253420209785428420233456008091632509255652343634529984400816700490470131093,
|
||||
6257781313532096835800460747082714697295034136932481743077166200794135826591,
|
||||
11966422202069200811427605007493817363680804416274031195624148724039857787313,
|
||||
8876022912542631074912834764773050492660953075192093830253524158063181475941,
|
||||
52049674541477055908813163364458131823806820044102483998576800878704568506967,
|
||||
6541832267666828237118069633374954748041800470865307468523599474646236580472,
|
||||
45442960117610900571098429443573054134827707854155326784175634232674544930715,
|
||||
42411304802662598148459339452254226615271657786988481684897413326989736031615],
|
||||
[51511939407083344002778208487678590135577660247075600880835916725469990319313,
|
||||
4386017178186728799761421274050927732938229436976005221436222062273391481632,
|
||||
663227665329044490605880474899933274574966982371072793854806732105730575244,
|
||||
7956955597245727322388196907364651338722736293265717471854714933795446618648,
|
||||
25615413494197319129070770032476622018948872899826892271961489884914005459090,
|
||||
44089542881006441891384034667061558189843302802581673885742427288293557612473,
|
||||
1330235044321395925144992814935234051203536271783948441776912650379638572084,
|
||||
50810734147355221866144137049300565722210413848092339398051685135286006925932],
|
||||
[46291121544435738125248657675097664742296276807186696922340332893747842754587,
|
||||
13820180736478645172746469075181304604729976364812127548341524461074783412926,
|
||||
21821175320697611197161277831984495658213397245419754392657307036488476373765,
|
||||
14806577897118234786495606424219372997573800509149076370951604526939593458489,
|
||||
4121259770197377590627011188630352152939645167495297314189270176024564981500,
|
||||
30919407268792259403824602884665561517383256626800433152413305048922095010897,
|
||||
11976519627445173558098140421995318477384771169277877503279343325183821276781,
|
||||
26967980286239502443715270897174999681242618240421470318851152333782809701734],
|
||||
[3650460179273129580093806058710273018999560093475503119057680216309578390988,
|
||||
40385222771838099109662234020243831589690223478794847201235014486200724862134,
|
||||
20738601554725926373596082603265918636164823648026470243422423735982938342408,
|
||||
25898290090014076279086638237202313571292864987698437102115051403552551578909,
|
||||
17027208157180086391192319363486696710451739452640092116905432497642111659971,
|
||||
45311967859890310071336359937788702458122841339624237957674250711373999964046,
|
||||
30801797608226447725817644589434252152704077439970597211826393252750837255264,
|
||||
46087155524659491087900373896182305256600235815109519358969365828449471244522],
|
||||
[45802223370746268123059159806400152299867771061127345631244786118574025749328,
|
||||
50306980075778262214155693291132052551559962723436936231611301042966928400825,
|
||||
9105861908793877437599087016640061747418296780065295891365798855886560153752,
|
||||
48177591413367409915642056167048753041735583848456612607691620273026228709602,
|
||||
7479286918288249337458111273748279770690595088312775476065356516306801980629,
|
||||
49779837246224071690294810803445084047795402193671669060746314363358914880825,
|
||||
43223717601022172097383565523190027152080076863600432708834283672429421806147,
|
||||
36115990427252817831519272511481477474123806352110831880569955844865152409554],
|
||||
[11798621276624967315721748990709309216351696098813162382053396097866233042733,
|
||||
34806952212038537244506031612074847133207330427265785757809673463434908473570,
|
||||
10559431278588446438155840088055546145087872298641007742921718770142881700525,
|
||||
2511742758961381498086249076485723904703122022711664665388729650078747694082,
|
||||
13058778062050708618301726264166109369024922071632328984390918925338427847716,
|
||||
22757381433196923491096449596295348042138602481479098385721617124187105273559,
|
||||
50435973648847072778532507268536698366596569483938905568975979489192305153887,
|
||||
9692044244906573895772196051455153467294816541497792469074445791662352057118],
|
||||
[42372918959432199162670834641599336326433006968669415662488070504036922966492,
|
||||
22755759419530071315007011572076166983660942447634027701351681157370705921018,
|
||||
8881354201366797207686592249590682298565723459695719800911380560885170725516,
|
||||
19725785152035256359574211351446161592903393017031483635806025440159666669692,
|
||||
38586107420291196905731314141240110021641762437995069426543221562298184751450,
|
||||
41983342504374430034240074906024700952180454895250182619374868616288213756381,
|
||||
24699580977072888772599627764765708101597323007812082074548828715213834751707,
|
||||
40903613549597429611399144365203839627850863176247809657126605147801691165582],
|
||||
[52181371244193189669553521955614617990714056725501643636576377752669773323445,
|
||||
30334172084294870556875274308904688414158741457854908094300017436690480001547,
|
||||
35548861917762862971011720475855172816698712671893796030607658203859222685056,
|
||||
23828822166916376664523534857031979764654878164406016294521947902346141831375,
|
||||
9525926338952422609290893812113350942492558421053540078000977304624217008060,
|
||||
51628644629799777637476595789175262638422034917782233018901952051044824901545,
|
||||
10527109078832366866417586795816864610030244893563632007270266203664988878415,
|
||||
11194215382192152257306835491684398858682370351821177979939632309447233186888],
|
||||
[23791984554824031672195249524658580601428376029501889159059009332107176394097,
|
||||
19832360622723392584029764807971325641132953515557801717644226271356492507876,
|
||||
5370567718707734490084045178883836972105253285449736908577321570876055642415,
|
||||
24072177097374519292068993110945703798030958684413852593268331853573451397392,
|
||||
51092856030717857607132039047789240547482897962295861318467321833280572912593,
|
||||
51610208211871924557451265725733951220616079019514789132032962359833072317205,
|
||||
14800890894612002638570836260269548031587506768363863797633541619652896335116,
|
||||
47927023617684282491494208201013569921672642612236042045401823798666133017562]
|
||||
];
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
function C_2_to_1() {
|
||||
return
|
||||
[
|
||||
39,
|
||||
41362478282768062297187132445775312675360473883834860695283235286481594490621,
|
||||
9548818195234740988996233204400874453525674173109474205108603996010297049928,
|
||||
25365440569177822667580105183435418073995888230868180942004497015015045856900,
|
||||
34023498397393406644117994167986720327178154686105264833093891093045919619309,
|
||||
38816051319719761886041858113129205506758421478656182868737326994635468402951,
|
||||
35167418087531820804128377095512663922179887277669504047069913414630376083753,
|
||||
25885868839756469722325652387535232478219821850603640827385444642154834700231,
|
||||
8867588811641202981080659274007552529205713737251862066053445622305818871963,
|
||||
36439756010140137556111047750162544185710881404522379792044818039722752946048,
|
||||
7788624504122357216765350546787885309160020166693449889975992574536033007374,
|
||||
3134147137704626983201116226440762775442116005053282329971088789984415999550,
|
||||
50252287380741824818995733304361249016282047978221591906573165442023106203143,
|
||||
48434698978712278012409706205559577163572452744833134361195687109159129985373,
|
||||
32960510617530186159512413633821386297955642598241661044178889571655571939473,
|
||||
12850897859166761094422335671106280470381427571695744605265713866647560628356,
|
||||
14578036872634298798382048587794204613583128573535557156943783762854124345644,
|
||||
21588109842058901916690548710649523388049643745013696896704903154857389904594,
|
||||
35731638686520516424752846654442973203189295883541072759390882351699754104989,
|
||||
34141830003233180772153845227433233456603143306530920011579259084215824391544,
|
||||
30272543670850635882116596228256005460817517173808721139136515002908946750291
|
||||
];
|
||||
}
|
||||
|
||||
function D_2_to_1() {
|
||||
return
|
||||
[
|
||||
14981678621464625851270783002338847382197300714436467949315331057125308909900,
|
||||
28253420209785428420233456008091632509255652343634529984400816700490470131093,
|
||||
51511939407083344002778208487678590135577660247075600880835916725469990319313,
|
||||
46291121544435738125248657675097664742296276807186696922340332893747842754587,
|
||||
3650460179273129580093806058710273018999560093475503119057680216309578390988,
|
||||
45802223370746268123059159806400152299867771061127345631244786118574025749328,
|
||||
11798621276624967315721748990709309216351696098813162382053396097866233042733,
|
||||
42372918959432199162670834641599336326433006968669415662488070504036922966492,
|
||||
52181371244193189669553521955614617990714056725501643636576377752669773323445,
|
||||
23791984554824031672195249524658580601428376029501889159059009332107176394097,
|
||||
33342520831620303764059548442834699069640109058400548818586964467754352720368,
|
||||
16791548253207744974576845515705461794133799104808996134617754018912057476556,
|
||||
11087343419860825311828133337767238110556416596687749174422888171911517001265,
|
||||
11931207770538477937808955037363240956790374856666237106403111503668796872571,
|
||||
3296943608590459582451043049934874894049468383833500962645016062634514172805,
|
||||
7080580976521357573320018355401935489220216583936865937104131954142364033647,
|
||||
25990144965911478244481527888046366474489820502460615136523859419965697796405,
|
||||
33907313384235729375566529911940467295099705980234607934575786561097199483218,
|
||||
25996950265608465541351207283024962044374873682152889814392533334239395044136,
|
||||
17878892320641464292190655092475335317049416605865175118054314040434534086821,
|
||||
25443622609028754422863910981890932539396181992608938932620284900889552530362
|
||||
];
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
function C_4_to_1() {
|
||||
return
|
||||
[
|
||||
[39,
|
||||
17756515227822460609684409997111995494590448775258437999344446424780281143353],
|
||||
[41362478282768062297187132445775312675360473883834860695283235286481594490621,
|
||||
3384073892082712848969991795331397937188893616190315628722966662742467187281],
|
||||
[9548818195234740988996233204400874453525674173109474205108603996010297049928,
|
||||
51311880822158488881090781617710146800056386303122657365679608608648067582435],
|
||||
[25365440569177822667580105183435418073995888230868180942004497015015045856900,
|
||||
29347609441914902330741511702270026847909178228078752565372729158237774700914],
|
||||
[34023498397393406644117994167986720327178154686105264833093891093045919619309,
|
||||
2339620320400167830454536231899316133967303509954474267430948538955691907104],
|
||||
[38816051319719761886041858113129205506758421478656182868737326994635468402951,
|
||||
27338042530319738113354246208426108832239651080023276643867223794985578055610],
|
||||
[35167418087531820804128377095512663922179887277669504047069913414630376083753,
|
||||
42192983528513372869128514327443204912824559545179630597589572656156258515752],
|
||||
[25885868839756469722325652387535232478219821850603640827385444642154834700231,
|
||||
42721818980548514490325424436763032046927347769153393863616095871384405840432],
|
||||
[8867588811641202981080659274007552529205713737251862066053445622305818871963,
|
||||
23473499332437056484066006746048591864129988909190267521144125882222313735740],
|
||||
[36439756010140137556111047750162544185710881404522379792044818039722752946048,
|
||||
16497366583607480604161417644040292299204496829635795525393416854929276060989],
|
||||
[7788624504122357216765350546787885309160020166693449889975992574536033007374,
|
||||
16727395967350522643500778393489915391834352737211416857240725807058479128000],
|
||||
[3134147137704626983201116226440762775442116005053282329971088789984415999550,
|
||||
46525506418681456193255596516104416743523037046982280449529426136392814992763],
|
||||
[50252287380741824818995733304361249016282047978221591906573165442023106203143,
|
||||
46030886964045328670650579467522042981756109464584907077434772786649263902996],
|
||||
[48434698978712278012409706205559577163572452744833134361195687109159129985373,
|
||||
19216533213230709497947223526297848065365334472367022650183395435586190711770]
|
||||
];
|
||||
}
|
||||
|
||||
function D_4_to_1() {
|
||||
return
|
||||
[
|
||||
[14981678621464625851270783002338847382197300714436467949315331057125308909900,
|
||||
48720959343719104324739338388885839802998711550637402773896395605948383052052],
|
||||
[28253420209785428420233456008091632509255652343634529984400816700490470131093,
|
||||
6257781313532096835800460747082714697295034136932481743077166200794135826591],
|
||||
[51511939407083344002778208487678590135577660247075600880835916725469990319313,
|
||||
4386017178186728799761421274050927732938229436976005221436222062273391481632],
|
||||
[46291121544435738125248657675097664742296276807186696922340332893747842754587,
|
||||
13820180736478645172746469075181304604729976364812127548341524461074783412926],
|
||||
[3650460179273129580093806058710273018999560093475503119057680216309578390988,
|
||||
40385222771838099109662234020243831589690223478794847201235014486200724862134],
|
||||
[45802223370746268123059159806400152299867771061127345631244786118574025749328,
|
||||
50306980075778262214155693291132052551559962723436936231611301042966928400825],
|
||||
[11798621276624967315721748990709309216351696098813162382053396097866233042733,
|
||||
34806952212038537244506031612074847133207330427265785757809673463434908473570],
|
||||
[42372918959432199162670834641599336326433006968669415662488070504036922966492,
|
||||
22755759419530071315007011572076166983660942447634027701351681157370705921018],
|
||||
[52181371244193189669553521955614617990714056725501643636576377752669773323445,
|
||||
30334172084294870556875274308904688414158741457854908094300017436690480001547],
|
||||
[23791984554824031672195249524658580601428376029501889159059009332107176394097,
|
||||
19832360622723392584029764807971325641132953515557801717644226271356492507876],
|
||||
[33342520831620303764059548442834699069640109058400548818586964467754352720368,
|
||||
5828182614154296575131381170785760240834851189333374788484657124381010655319],
|
||||
[16791548253207744974576845515705461794133799104808996134617754018912057476556,
|
||||
23729797853490401568967730686618146850735129707152853256809050789424668284094],
|
||||
[11087343419860825311828133337767238110556416596687749174422888171911517001265,
|
||||
22848708497596347027267124890363029002241440143993561170521113640580467699956],
|
||||
[11931207770538477937808955037363240956790374856666237106403111503668796872571,
|
||||
51131682674615117766578358255722474622484771145670260043231096654077231782319]
|
||||
];
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
TAU=../../../keys/powersOfTau20_BLS_final.ptau
|
||||
|
||||
circom "$1.circom" --r1cs --wasm -p bls12381
|
||||
cd "$1_js/"
|
||||
node generate_witness.js "$1.wasm" ../input.json ../witness.wtns
|
||||
cd ..
|
||||
rm -R "$1_js/"
|
||||
snarkjs groth16 setup "$1.r1cs" $TAU circuit_0000.zkey -v
|
||||
snarkjs zkey contribute circuit_0000.zkey circuit_0001.zkey --name="1st Contributor Name" -e="entropy" -v
|
||||
snarkjs zkey beacon circuit_0001.zkey "$1.zkey" 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon phase2" -v
|
||||
snarkjs zkey export verificationkey "$1.zkey" verification_key.json -v
|
||||
|
||||
rm circuit_0*
|
||||
|
||||
|
||||
|
||||
|
||||
#for i in `seq 1 20`;
|
||||
#do
|
||||
# ../../../rapidsnark/package/bin/prover "$1.zkey" witness.wtns proof.json public.json
|
||||
snarkjs groth16 prove "$1.zkey" witness.wtns proof.json public.json
|
||||
#done
|
||||
|
||||
|
||||
|
||||
#start=$(date +%s%6N)
|
||||
#for i in `seq 1 100`;
|
||||
#do
|
||||
snarkjs groth16 prove "$1.zkey" witness.wtns proof.json public.json
|
||||
#../../../rapidsnark/package/bin/prover "$1.zkey" witness.wtns proof.json public.json
|
||||
#done
|
||||
|
||||
|
||||
#end=$(date +%s%6N)
|
||||
|
||||
|
||||
|
||||
rm witness.wtns
|
||||
|
||||
snarkjs groth16 verify verification_key.json public.json proof.json
|
||||
|
||||
#temps=$((($end-$start)/100))
|
||||
#echo "Temps de la preuve: $temps micro secondes "
|
||||
|
||||
rm "$1.zkey"
|
||||
@ -1,473 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon_Jubjub_16_to_1_constants.circom";
|
||||
|
||||
template external_linear_layer_16_to_1() {
|
||||
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
// Matrix is [10 14 2 6 5 7 1 3 5 7 1 3 5 7 1 3]
|
||||
// [ 8 12 2 2 4 6 1 1 4 6 1 1 4 6 1 1]
|
||||
// [ 2 6 10 14 1 3 5 7 1 3 5 7 1 3 5 7]
|
||||
// [ 2 2 8 12 1 1 4 6 1 1 4 6 1 1 4 6]
|
||||
// [ 5 7 1 3 10 14 2 6 5 7 1 3 5 7 1 3]
|
||||
// [ 4 6 1 1 8 12 2 2 4 6 1 1 4 6 1 1]
|
||||
// [ 1 3 5 7 2 6 10 14 1 3 5 7 1 3 5 7]
|
||||
// [ 1 1 4 6 2 2 8 12 1 1 4 6 1 1 4 6]
|
||||
// [ 5 7 1 3 5 7 1 3 10 14 2 6 5 7 1 3]
|
||||
// [ 4 6 1 1 4 6 1 1 8 12 2 2 4 6 1 1]
|
||||
// [ 1 3 5 7 1 3 5 7 2 6 10 14 1 3 5 7]
|
||||
// [ 1 1 4 6 1 1 4 6 2 2 8 12 1 1 4 6]
|
||||
// [ 5 7 1 3 5 7 1 3 5 7 1 3 10 14 2 6]
|
||||
// [ 4 6 1 1 4 6 1 1 4 6 1 1 8 12 2 2]
|
||||
// [ 1 3 5 7 1 3 5 7 1 3 5 7 2 6 10 14]
|
||||
// [ 1 1 4 6 1 1 4 6 1 1 4 6 2 2 8 12]
|
||||
|
||||
out[0] <== in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +
|
||||
in[7] +in[7] +in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +
|
||||
in[11] +in[11] +in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +
|
||||
in[15] +in[15] +in[15];
|
||||
|
||||
out[1] <== in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +in[2] +
|
||||
in[3] +in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +
|
||||
in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +
|
||||
in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +
|
||||
in[15];
|
||||
|
||||
out[2] <== in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +
|
||||
in[5] +in[5] +in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +
|
||||
in[9] +in[9] +in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +
|
||||
in[13] +in[13] +in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[3] <== in[0] +in[0] +
|
||||
in[1] +in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +
|
||||
in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +
|
||||
in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +
|
||||
in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[4] <== in[0] +in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +
|
||||
in[3] +in[3] +in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +
|
||||
in[11] +in[11] +in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +
|
||||
in[15] +in[15] +in[15];
|
||||
|
||||
out[5] <== in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +
|
||||
in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +in[6] +
|
||||
in[7] +in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +
|
||||
in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +
|
||||
in[15];
|
||||
|
||||
out[6] <== in[0] +
|
||||
in[1] +in[1] +in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +
|
||||
in[9] +in[9] +in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +
|
||||
in[13] +in[13] +in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[7] <== in[0] +
|
||||
in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +in[4] +
|
||||
in[5] +in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +
|
||||
in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +
|
||||
in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[8] <== in[0] +in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +
|
||||
in[3] +in[3] +in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +
|
||||
in[7] +in[7] +in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +
|
||||
in[15] +in[15] +in[15];
|
||||
|
||||
out[9] <== in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +
|
||||
in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +
|
||||
in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +in[10] +
|
||||
in[11] +in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +
|
||||
in[15];
|
||||
|
||||
out[10] <== in[0] +
|
||||
in[1] +in[1] +in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +
|
||||
in[5] +in[5] +in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +
|
||||
in[13] +in[13] +in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[11] <== in[0] +
|
||||
in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +
|
||||
in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +in[8] +
|
||||
in[9] +in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +
|
||||
in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[12] <== in[0] +in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +
|
||||
in[3] +in[3] +in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +
|
||||
in[7] +in[7] +in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +
|
||||
in[11] +in[11] +in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[13] <== in[0] +in[0] +in[0] +in[0] +
|
||||
in[1] +in[1] +in[1] +in[1] +in[1] +in[1] +
|
||||
in[2] +
|
||||
in[3] +
|
||||
in[4] +in[4] +in[4] +in[4] +
|
||||
in[5] +in[5] +in[5] +in[5] +in[5] +in[5] +
|
||||
in[6] +
|
||||
in[7] +
|
||||
in[8] +in[8] +in[8] +in[8] +
|
||||
in[9] +in[9] +in[9] +in[9] +in[9] +in[9] +
|
||||
in[10] +
|
||||
in[11] +
|
||||
in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +in[14] +
|
||||
in[15] +in[15];
|
||||
|
||||
out[14] <== in[0] +
|
||||
in[1] +in[1] +in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +
|
||||
in[5] +in[5] +in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +
|
||||
in[9] +in[9] +in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +in[12] +
|
||||
in[13] +in[13] +in[13] +in[13] +in[13] +in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
|
||||
out[15] <== in[0] +
|
||||
in[1] +
|
||||
in[2] +in[2] +in[2] +in[2] +
|
||||
in[3] +in[3] +in[3] +in[3] +in[3] +in[3] +
|
||||
in[4] +
|
||||
in[5] +
|
||||
in[6] +in[6] +in[6] +in[6] +
|
||||
in[7] +in[7] +in[7] +in[7] +in[7] +in[7] +
|
||||
in[8] +
|
||||
in[9] +
|
||||
in[10] +in[10] +in[10] +in[10] +
|
||||
in[11] +in[11] +in[11] +in[11] +in[11] +in[11] +
|
||||
in[12] +in[12] +
|
||||
in[13] +in[13] +
|
||||
in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +in[14] +
|
||||
in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15] +in[15];
|
||||
}
|
||||
|
||||
template internal_linear_layer_16_to_1() {
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
signal sum <== in[0] + in[1] + in[2] + in[3] + in[4] + in[5] + in[6] + in[7] + in[8] + in[9] + in[10] + in[11] + in[12] + in[13] + in[14] + in[15];
|
||||
|
||||
|
||||
out[0] <== in[0] * 67 + sum;
|
||||
out[1] <== in[1] * 84 + sum;
|
||||
out[2] <== in[2] * 80 + sum;
|
||||
out[3] <== in[3] * 94 + sum;
|
||||
out[4] <== in[4] * 57 + sum;
|
||||
out[5] <== in[5] * 89 + sum;
|
||||
out[6] <== in[6] * 92 + sum;
|
||||
out[7] <== in[7] * 39 + sum;
|
||||
out[8] <== in[8] * 34 + sum;
|
||||
out[9] <== in[9] * 24 + sum;
|
||||
out[10] <== in[10] + sum;
|
||||
out[11] <== in[11] * 95 + sum;
|
||||
out[12] <== in[12] * 21 + sum;
|
||||
out[13] <== in[13] * 73 + sum;
|
||||
out[14] <== in[14] * 68 + sum;
|
||||
out[15] <== in[15] * 52 + sum;
|
||||
|
||||
}
|
||||
|
||||
template sbox_16_to_1() { // ALPHA = 5
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2 * in2;
|
||||
out <== in4 * in;
|
||||
}
|
||||
|
||||
template ARC_16_to_1(index){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
var constants[185] = round_constant_16_to_1();
|
||||
|
||||
out <== in + constants[index];
|
||||
}
|
||||
|
||||
|
||||
template partial_round_16_to_1(round_number) {
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
component add_constant = ARC_16_to_1(round_number + 60);
|
||||
add_constant.in <== in[0];
|
||||
|
||||
component exp = sbox_16_to_1();
|
||||
exp.in <== add_constant.out;
|
||||
|
||||
component matrix = internal_linear_layer_16_to_1();
|
||||
matrix.in[0] <== exp.out;
|
||||
for(var i=1; i<16; i++){
|
||||
matrix.in[i] <== in[i];
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
out[i] <== matrix.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template full_rounds_16_to_1(round_number){
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
component add_constant[16];
|
||||
if(round_number < 4) {
|
||||
for(var i=0; i<16; i++){
|
||||
add_constant[i] = ARC_16_to_1(round_number*16+i);
|
||||
}
|
||||
} else {
|
||||
for(var i=0; i<16; i++){
|
||||
add_constant[i] = ARC_16_to_1((round_number - 61) * 16 + i + 121);
|
||||
}
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
add_constant[i].in <== in[i];
|
||||
}
|
||||
|
||||
component exp[16];
|
||||
for(var i=0; i<16; i++){
|
||||
exp[i] = sbox_16_to_1();
|
||||
exp[i].in <== add_constant[i].out;
|
||||
}
|
||||
|
||||
component matrix = external_linear_layer_16_to_1();
|
||||
for(var i=0; i<16; i++){
|
||||
matrix.in[i] <== exp[i].out;
|
||||
}
|
||||
for(var i=0; i<16; i++){
|
||||
out[i] <== matrix.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template permutation_16_to_1(){
|
||||
signal input in[16];
|
||||
signal output out[16];
|
||||
|
||||
component full_rounds_16_to_1[8];
|
||||
component partial_round_16_to_1s[57];
|
||||
component matrix = external_linear_layer_16_to_1();
|
||||
|
||||
for(var i=0; i<16; i++){
|
||||
matrix.in[i] <== in[i];
|
||||
}
|
||||
|
||||
for(var i=0; i<65; i++){
|
||||
if(i < 4) {
|
||||
full_rounds_16_to_1[i] = full_rounds_16_to_1(i);
|
||||
} else {
|
||||
if(i<61) {
|
||||
partial_round_16_to_1s[i-4] = partial_round_16_to_1(i);
|
||||
} else {
|
||||
full_rounds_16_to_1[i-57] = full_rounds_16_to_1(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<16; i++){
|
||||
full_rounds_16_to_1[0].in[i] <== matrix.out[i];
|
||||
}
|
||||
|
||||
for(var i=1; i<4; i++){
|
||||
for(var j=0; j<16; j++){
|
||||
full_rounds_16_to_1[i].in[j] <== full_rounds_16_to_1[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<16; i++){
|
||||
partial_round_16_to_1s[0].in[i] <== full_rounds_16_to_1[3].out[i];
|
||||
}
|
||||
|
||||
for(var i=1; i<57; i++){
|
||||
for(var j=0; j<16; j++){
|
||||
partial_round_16_to_1s[i].in[j] <== partial_round_16_to_1s[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<16; i++){
|
||||
full_rounds_16_to_1[4].in[i] <== partial_round_16_to_1s[56].out[i];
|
||||
}
|
||||
|
||||
for(var i=5; i<8; i++){
|
||||
for(var j=0; j<16; j++){
|
||||
full_rounds_16_to_1[i].in[j] <== full_rounds_16_to_1[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<16; i++){
|
||||
out[i] <== full_rounds_16_to_1[7].out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template hash_16_to_1(){
|
||||
signal input in[16];
|
||||
signal output out;
|
||||
|
||||
component perm = permutation_16_to_1();
|
||||
for(var i=0; i<16; i++){
|
||||
perm.in[i] <== in[i];
|
||||
}
|
||||
|
||||
out <== in[0] + perm.out[0];
|
||||
}
|
||||
|
||||
//component main = hash_16_to_1();
|
||||
@ -1,147 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon_Jubjub_2_to_1_constants.circom";
|
||||
|
||||
template linear_layer_2_to_1() {
|
||||
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <== in[0] + in[0] + in[1];
|
||||
out[1] <== in[0] + in[1] + in[1];
|
||||
}
|
||||
|
||||
template sbox_2_to_1() { // ALPHA = 5
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2 * in2;
|
||||
out <== in4 * in;
|
||||
}
|
||||
|
||||
template ARC_2_to_1(index){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
var constants[72] = round_constant_2_to_1();
|
||||
|
||||
out <== in + constants[index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
template partial_round_2_to_1(round_number) {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
component add_constant = ARC_2_to_1(round_number + 4);
|
||||
add_constant.in <== in[0];
|
||||
|
||||
component exp = sbox_2_to_1();
|
||||
exp.in <== add_constant.out;
|
||||
|
||||
component matrix = linear_layer_2_to_1();
|
||||
matrix.in[0] <== exp.out;
|
||||
matrix.in[1] <== in[1];
|
||||
|
||||
out[0] <== matrix.out[0];
|
||||
out[1] <== matrix.out[1];
|
||||
}
|
||||
|
||||
template full_rounds_2_to_1(round_number){
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
component add_constant[2];
|
||||
if(round_number < 4) {
|
||||
add_constant[0] = ARC_2_to_1(round_number*2);
|
||||
add_constant[1] = ARC_2_to_1(round_number*2 +1);
|
||||
} else {
|
||||
add_constant[0] = ARC_2_to_1((round_number - 60) * 2 + 64);
|
||||
add_constant[1] = ARC_2_to_1((round_number - 60) * 2 + 65);
|
||||
}
|
||||
add_constant[0].in <== in[0];
|
||||
add_constant[1].in <== in[1];
|
||||
|
||||
component exp[2];
|
||||
exp[0] = sbox_2_to_1();
|
||||
exp[1] = sbox_2_to_1();
|
||||
exp[0].in <== add_constant[0].out;
|
||||
exp[1].in <== add_constant[1].out;
|
||||
|
||||
component matrix = linear_layer_2_to_1();
|
||||
matrix.in[0] <== exp[0].out;
|
||||
matrix.in[1] <== exp[1].out;
|
||||
|
||||
out[0] <== matrix.out[0];
|
||||
out[1] <== matrix.out[1];
|
||||
}
|
||||
|
||||
template permutation_2_to_1(){
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
component full_rounds_2_to_1[8];
|
||||
component partial_round_2_to_1s[56];
|
||||
component matrix = linear_layer_2_to_1();
|
||||
|
||||
matrix.in[0] <== in[0];
|
||||
matrix.in[1] <== in[1];
|
||||
|
||||
for(var i=0; i<64; i++){
|
||||
if(i < 4) {
|
||||
full_rounds_2_to_1[i] = full_rounds_2_to_1(i);
|
||||
} else {
|
||||
if(i<60) {
|
||||
partial_round_2_to_1s[i-4] = partial_round_2_to_1(i);
|
||||
} else {
|
||||
full_rounds_2_to_1[i-56] = full_rounds_2_to_1(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
full_rounds_2_to_1[0].in[0] <== matrix.out[0];
|
||||
full_rounds_2_to_1[0].in[1] <== matrix.out[1];
|
||||
|
||||
for(var i=1; i<4; i++){
|
||||
full_rounds_2_to_1[i].in[0] <== full_rounds_2_to_1[i-1].out[0];
|
||||
full_rounds_2_to_1[i].in[1] <== full_rounds_2_to_1[i-1].out[1];
|
||||
}
|
||||
|
||||
partial_round_2_to_1s[0].in[0] <== full_rounds_2_to_1[3].out[0];
|
||||
partial_round_2_to_1s[0].in[1] <== full_rounds_2_to_1[3].out[1];
|
||||
|
||||
for(var i=1; i<56; i++){
|
||||
partial_round_2_to_1s[i].in[0] <== partial_round_2_to_1s[i-1].out[0];
|
||||
partial_round_2_to_1s[i].in[1] <== partial_round_2_to_1s[i-1].out[1];
|
||||
}
|
||||
|
||||
full_rounds_2_to_1[4].in[0] <== partial_round_2_to_1s[55].out[0];
|
||||
full_rounds_2_to_1[4].in[1] <== partial_round_2_to_1s[55].out[1];
|
||||
|
||||
for(var i=5; i<8; i++){
|
||||
full_rounds_2_to_1[i].in[0] <== full_rounds_2_to_1[i-1].out[0];
|
||||
full_rounds_2_to_1[i].in[1] <== full_rounds_2_to_1[i-1].out[1];
|
||||
}
|
||||
|
||||
out[0] <== full_rounds_2_to_1[7].out[0];
|
||||
out[1] <== full_rounds_2_to_1[7].out[1];
|
||||
}
|
||||
|
||||
template hash_2_to_1(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component perm = permutation_2_to_1();
|
||||
perm.in[0] <== in[0];
|
||||
perm.in[1] <== in[1];
|
||||
|
||||
out <== in[0] + perm.out[0];
|
||||
}
|
||||
|
||||
//component main = hash_2_to_1();
|
||||
@ -1,188 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "poseidon_Jubjub_4_to_1_constants.circom";
|
||||
|
||||
template external_linear_layer_4_to_1() {
|
||||
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
|
||||
out[3] <== in[0] + in[0] + in[0] + in[0] + in[0] + in[1] + in[1] + in[1] + in[1] + in[1] + in[1] + in[1] + in[2] + in[3] + in[3] + in[3];
|
||||
out[1] <== in[0] + in[0] + in[0] + in[0] + in[1] + in[1] + in[1] + in[1] + in[1] + in[1] + in[2] + in[3];
|
||||
out[0] <== in[0] + in[1] + in[1] + in[1] + in[2] + in[2] + in[2] + in[2] + in[2] + in[3] + in[3] + in[3] + in[3] + in[3] + in[3] + in[3];
|
||||
out[2] <== in[0] + in[1] + in[2] + in[2] + in[2] + in[2] + in[3] + in[3] + in[3] + in[3] + in[3] + in[3];
|
||||
}
|
||||
|
||||
template internal_linear_layer_4_to_1() {
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
out[0] <== in[0] + in[0] + in[1] + in[2] + in[3];
|
||||
out[1] <== in[1] + in[0] + in[1] + in[2] + in[3];
|
||||
out[2] <== in[2] + in[2] + in[2] + in[0] + in[1] + in[2] + in[3];
|
||||
out[3] <== in[3] + in[3] + in[3] + in[3] + in[3] + in[3] + in[3] + in[0] + in[1] + in[2] + in[3];
|
||||
}
|
||||
|
||||
template sbox_4_to_1() { // ALPHA = 5
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2 * in2;
|
||||
out <== in4 * in;
|
||||
}
|
||||
|
||||
template ARC_4_to_1(index){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
var constants[88] = round_constant_4_to_1();
|
||||
|
||||
out <== in + constants[index];
|
||||
}
|
||||
|
||||
|
||||
template partial_round_4_to_1(round_number) {
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
component add_constant = ARC_4_to_1(round_number + 12);
|
||||
add_constant.in <== in[0];
|
||||
|
||||
component exp = sbox_4_to_1();
|
||||
exp.in <== add_constant.out;
|
||||
|
||||
component matrix = internal_linear_layer_4_to_1();
|
||||
matrix.in[0] <== exp.out;
|
||||
matrix.in[1] <== in[1];
|
||||
matrix.in[2] <== in[2];
|
||||
matrix.in[3] <== in[3];
|
||||
|
||||
out[0] <== matrix.out[0];
|
||||
out[1] <== matrix.out[1];
|
||||
out[2] <== matrix.out[2];
|
||||
out[3] <== matrix.out[3];
|
||||
}
|
||||
|
||||
template full_rounds_4_to_1(round_number){
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
component add_constant[4];
|
||||
if(round_number < 4) {
|
||||
add_constant[0] = ARC_4_to_1(round_number*4);
|
||||
add_constant[1] = ARC_4_to_1(round_number*4 +1);
|
||||
add_constant[2] = ARC_4_to_1(round_number*4 +2);
|
||||
add_constant[3] = ARC_4_to_1(round_number*4 +3);
|
||||
} else {
|
||||
add_constant[0] = ARC_4_to_1((round_number - 60) * 4 + 72);
|
||||
add_constant[1] = ARC_4_to_1((round_number - 60) * 4 + 73);
|
||||
add_constant[2] = ARC_4_to_1((round_number - 60) * 4 + 74);
|
||||
add_constant[3] = ARC_4_to_1((round_number - 60) * 4 + 75);
|
||||
}
|
||||
add_constant[0].in <== in[0];
|
||||
add_constant[1].in <== in[1];
|
||||
add_constant[2].in <== in[2];
|
||||
add_constant[3].in <== in[3];
|
||||
|
||||
component exp[4];
|
||||
exp[0] = sbox_4_to_1();
|
||||
exp[1] = sbox_4_to_1();
|
||||
exp[2] = sbox_4_to_1();
|
||||
exp[3] = sbox_4_to_1();
|
||||
exp[0].in <== add_constant[0].out;
|
||||
exp[1].in <== add_constant[1].out;
|
||||
exp[2].in <== add_constant[2].out;
|
||||
exp[3].in <== add_constant[3].out;
|
||||
|
||||
component matrix = external_linear_layer_4_to_1();
|
||||
matrix.in[0] <== exp[0].out;
|
||||
matrix.in[1] <== exp[1].out;
|
||||
matrix.in[2] <== exp[2].out;
|
||||
matrix.in[3] <== exp[3].out;
|
||||
|
||||
out[0] <== matrix.out[0];
|
||||
out[1] <== matrix.out[1];
|
||||
out[2] <== matrix.out[2];
|
||||
out[3] <== matrix.out[3];
|
||||
}
|
||||
|
||||
template permutation_4_to_1(){
|
||||
signal input in[4];
|
||||
signal output out[4];
|
||||
|
||||
component full_rounds_4_to_1[8];
|
||||
component partial_round_4_to_1s[56];
|
||||
component matrix = external_linear_layer_4_to_1();
|
||||
|
||||
matrix.in[0] <== in[0];
|
||||
matrix.in[1] <== in[1];
|
||||
matrix.in[2] <== in[2];
|
||||
matrix.in[3] <== in[3];
|
||||
|
||||
for(var i=0; i<64; i++){
|
||||
if(i < 4) {
|
||||
full_rounds_4_to_1[i] = full_rounds_4_to_1(i);
|
||||
} else {
|
||||
if(i<60) {
|
||||
partial_round_4_to_1s[i-4] = partial_round_4_to_1(i);
|
||||
} else {
|
||||
full_rounds_4_to_1[i-56] = full_rounds_4_to_1(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<4; i++){
|
||||
full_rounds_4_to_1[0].in[i] <== matrix.out[i];
|
||||
}
|
||||
|
||||
for(var i=1; i<4; i++){
|
||||
for(var j=0; j<4; j++){
|
||||
full_rounds_4_to_1[i].in[j] <== full_rounds_4_to_1[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<4; i++){
|
||||
partial_round_4_to_1s[0].in[i] <== full_rounds_4_to_1[3].out[i];
|
||||
}
|
||||
|
||||
for(var i=1; i<56; i++){
|
||||
for(var j=0; j<4; j++){
|
||||
partial_round_4_to_1s[i].in[j] <== partial_round_4_to_1s[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<4; i++){
|
||||
full_rounds_4_to_1[4].in[i] <== partial_round_4_to_1s[55].out[i];
|
||||
}
|
||||
|
||||
for(var i=5; i<8; i++){
|
||||
for(var j=0; j<4; j++){
|
||||
full_rounds_4_to_1[i].in[j] <== full_rounds_4_to_1[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<4; i++){
|
||||
out[i] <== full_rounds_4_to_1[7].out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template hash_4_to_1(){
|
||||
signal input in[4];
|
||||
signal output out;
|
||||
|
||||
component perm = permutation_4_to_1();
|
||||
perm.in[0] <== in[0];
|
||||
perm.in[1] <== in[1];
|
||||
perm.in[2] <== in[2];
|
||||
perm.in[3] <== in[3];
|
||||
|
||||
out <== in[0] + perm.out[0];
|
||||
}
|
||||
|
||||
//component main = hash_4_to_1();
|
||||
@ -1,193 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
function round_constant_16_to_1() {
|
||||
return
|
||||
[
|
||||
39725799400017827115953999199803965513668921247606107843235739645000498452181,
|
||||
42966428960558994593504354654034020585855169251008976179361555763424614464338,
|
||||
1902577049757491257818576950592390026062184527103985176709404045325719879153,
|
||||
44431672934524375006946320990995907220611992982569305140824479722873832750184,
|
||||
39726183949244760384768131039650643342100328144953562677717530936076214603575,
|
||||
47922249389084318636163655667342945193486098112364797914711366318805271081986,
|
||||
1862870272947949400931550187895813583996084263112126758587127421895920740217,
|
||||
4609552006052426829558648842629624826577232105300129098751251434249497379415,
|
||||
35588143488957689566276930373759329909335354222484070944945535758095890233602,
|
||||
31992851211763793548423275170246297274462525072830105768609534303798701174374,
|
||||
10431109178659867018016774068824625279897747730577584847579124215705854088752,
|
||||
1949666570245048798153069638552026706752846020986409274673577266743024227986,
|
||||
26013146320492118585809324011747055383255013664810283913111923543378165512435,
|
||||
24326326384498087823059984407171843358848416830861907662385192677188116053544,
|
||||
22319685994625011021753350147173406654223939569203496437101532456482753075879,
|
||||
50557239558368781744228704045005139069258908206255515650400270553037541504198,
|
||||
8150349453804124148576142676639616213878444242674057629308915686941165448719,
|
||||
48208850819924081505370182430049176104131115325038330030896851480045955495846,
|
||||
23292055228237110741391983617517431423114804124284097964494568447865687504083,
|
||||
41624195613852190072343927309438239744583865875755371975404916906916622520312,
|
||||
35035764767249963834124347515646744980548162618519514861977709647292192162935,
|
||||
4779348796643887084014079273412324900195658451616750603184150546614709227590,
|
||||
33367047533960399900339953965992791362189146117008495287189183308885826514987,
|
||||
47818152023063189199872106125697047204743569529570459808477570336306405682618,
|
||||
42796246674763432543587686312218067656639355734975037053737259369488219415432,
|
||||
10957190869792979750714342710039883244593973691851341486138757518667861871308,
|
||||
2841790402482039728028394542789470351099439451234544313142331893197703007354,
|
||||
16616683520944631525798957628064854348665295295102366742591213566889088018633,
|
||||
33567370488316680379461825404457605756079279555675131093451020281219258632141,
|
||||
20149108407482774388930550024591991805677394222603241325670591147763821350175,
|
||||
26521955033333972827600806868235450804729772994352860271090218480508888628468,
|
||||
30420917495722730561485028971813175058988495495112448737909833585405582002453,
|
||||
28826298253194385387635350229770135429043506867664273190337060583321839575111,
|
||||
17917025733340975563320009027981039582040740238333569779892727038742964339095,
|
||||
7141322642265363206186621258281581108534976046127258038741170240455221165198,
|
||||
19418423356096329136327193014171723261000987171654451855537930843119849003480,
|
||||
4435246673426368856651403911455319600556213204117162371080963632405613232527,
|
||||
19632896986964074847700416879011202636067522051661757108806676985789880273707,
|
||||
27046963462399353439595827223611516072637119359583733706532920096544318625175,
|
||||
46022420944605380770914903892871308087212302911540340258773948901501361016991,
|
||||
47210247379686065208769144617004411377616699091411215517824991959313614962397,
|
||||
10113618698993232512425817656261980665816667005776383524586380129027083138291,
|
||||
35517438329843448024913764440686318451400431892618552836051616554728503908001,
|
||||
15621081553202567263286903894992975334527971102321162065809849644051230558156,
|
||||
29674547690110160534416981628193785576251233526911087635787729103482288097393,
|
||||
48072441526206759351688872909792052037070864282054279767041551741286737196367,
|
||||
41744043803776630924388673324290707208134439478043126394378048339212169592401,
|
||||
9628276074092566929694879552911540910341944885042275367756464425374067624509,
|
||||
20632626646113120307999197184021140185329277351497138331616553936227435116058,
|
||||
20792210528194122935550939155383235642592438080224243249333876170013316543401,
|
||||
40415491313636855559381927040556471386850767350804210034574345185034062472388,
|
||||
42065986796325477298062230949689861704213331366919061593388137948694441619250,
|
||||
40821207536769008545206744063766400532504619210533302382117795523897539697933,
|
||||
25553665219208663753910822024028906032034541099513008737546655361577447316484,
|
||||
19736663029664934322245808384029169299382853413147390505477065761633976373362,
|
||||
41037270906646381161943193245472673282253590700725246354740042685574618941505,
|
||||
26465673628980636091049213717769341512445753008415873261263203826832299352951,
|
||||
37036784788783168689308644616358821855616430701564621669397983274253847911044,
|
||||
16882309834972349171728263406452316383132803207143172570189837375172214690963,
|
||||
49236009794362178305819055463654400779656334164463557593816047235183326696206,
|
||||
39126492963181209630544294313956192397928968809823631059639413986679789778216,
|
||||
43658389378690206885714590070566109002458688834417247158444257250935092974665,
|
||||
16333104498316984295745962415236263230477082737132070203651697035209925593266,
|
||||
2343404888674146320460570191540978518333195833255755810571688909855019156349,
|
||||
24634045350057319695041104791403403368011675948761890270733136933077818947573,
|
||||
24387229815091645818728740871562656675244609698356948940855886553509325623218,
|
||||
34856435078036813743723173976791961760363416490222768467602434757897150562809,
|
||||
22463928646505673196264844647723745514489344400622648158270067812328221291172,
|
||||
38337547475660790190067897986042722249254601625800102257245591381379028610987,
|
||||
30884758170575514019575313258747378429451169785327990741538528539964746232511,
|
||||
407062347257081198418184706020217550797090175697390265997395699504028840069,
|
||||
46072527669630030314941843287930470349120547732416735746099013950369555752487,
|
||||
26598420173680844002096268043589508593110520210883302319058895397482348813138,
|
||||
5468186730708689095665003796421147031372937271113374556364693295567666309881,
|
||||
20408443200377694476685908188621206365577738334727573068844969120059071063384,
|
||||
46981234183655934922934842049383026387012791700440415493493702691352740266098,
|
||||
33551792494519814298680232023513160371021410923276291252829879529580574549607,
|
||||
44191750214736553132933384320160073484141698637542792822319467448466449199959,
|
||||
52082663085085422534369913780529050462333401292522763448650886744352341477846,
|
||||
43609725693554764598774802211508572436819354508573541391712385270827954088014,
|
||||
5509314597941212988576665300843166762362117860942586466472903661374654433047,
|
||||
5559029914528165704027960512924831270184459421996344081783499760333465840454,
|
||||
33524678638941473952008777383950476291303669122863259465508971654565607710124,
|
||||
45645434759869537782219495003520693614316744086502894675070357053578529462611,
|
||||
21634412361943063812483816878212759698145592627132630568177240468236243443997,
|
||||
17296076019245918134776233380747899670718046224411673517180705100767962406954,
|
||||
51440070128252977573576752509509289893411386048688470945863901737258119109741,
|
||||
3594222373894239759942466635754825806993182513993455014470212549644348436736,
|
||||
47959769456918498933526528689384868494120276948030111429507861237362437496210,
|
||||
33000764793048989170342190628396476268404452069453776919602031823454420654656,
|
||||
42826490422129152698636386897788577399393533635964594559886553174637239521118,
|
||||
52295329105725197789753101315429895369766102629019133090017712989241053783558,
|
||||
47880622238513674104247747676583724803255466382975859845069693487703628947714,
|
||||
43936946713208191402441184330937985658846334880823513129204372649490118165491,
|
||||
40251165390594695927371248080107666232732935108005358445481599233717782638896,
|
||||
4374561185857417857316731922491353498974134405011029557830297994813315862559,
|
||||
36035028519117241692429568027060454516008330481155302030640451954673337039870,
|
||||
17169679336575379664065214518686885005225695064353947035596355048982268831028,
|
||||
15880917696586343406953592641564615996605082216639892270189959812763710888748,
|
||||
44053791831887360310582759225296188780718960772971991969178524168816504578804,
|
||||
17891697801976794338721931255832783817787274947410906666444514892619618334272,
|
||||
41860684084301922118560078323296728501588433716011882280914057750677004252514,
|
||||
39634237355488544158215275263851269921534055658196710011242793797355974120931,
|
||||
17147446725471655980188874591608844349450837795690392086436662207272648235970,
|
||||
19402693173125609969856950331264436884921152880190529800026177590116055294038,
|
||||
10691603198079109355998270513275267963583839999640707229593969158192066085397,
|
||||
47540627356602773888603132684733863602762111482745208345804634126586257262607,
|
||||
5915674545476155673196233396217928914866410645604699985302660208523245942237,
|
||||
111251938011213760763774859243277527837142141250061606873636423012197111197,
|
||||
35063286980316874255015992522343006303508619821794962259547057506813060931773,
|
||||
4955838234826402705564139094252802999139115369004968713576517960060305039082,
|
||||
13792409982596927634720969816052864004355280343403291329940320489270508883803,
|
||||
35825741100880023876488868468112742657673252321462610504266451341355067205610,
|
||||
28460915945533593428542040906830378549800618474095963851867763677018897302929,
|
||||
9713844506249087416664024364428812240068094374028199286225738527757038112467,
|
||||
40679805732400884118723774115665481614915421978306297159251228478606230752474,
|
||||
29757946798627258745416990533455815630324656030573466209153051560180917776353,
|
||||
48357362019104750186375328819952102172608585465016965207540831676602884269263,
|
||||
32940491071431805169868501574465967021193902185553749640148719707932598780469,
|
||||
7473125368630470049034003737446766486818477818719886735195316440180323968735,
|
||||
49797314418731632305394406125363649977467316746705136554158771555038756351980,
|
||||
29423812245635343436136357631167744312439395772431168176499761020256672974116,
|
||||
17752952597488467689955328967514036081230334268062286286791238444994797946364,
|
||||
11187314008830530006226896925828877981837282277801039676209354309840830166312,
|
||||
1460570367181490316969148060693926446394822620570366788008558284806968117734,
|
||||
2845512215983531260468619146202988365036283019984734085030635808663534080897,
|
||||
13678775934492824068869109923010846046122089274150470818447401546000515089448,
|
||||
41560010339997824874371372926655493150700423413706122338193288307311885566768,
|
||||
44104701369840880307377204949341973251175518351389507661546336745348450403920,
|
||||
16099171949124285044549692766555664705752094379574657435086067387762269145164,
|
||||
10885502210016683506969436609216522437947532105991633231562168011909638111557,
|
||||
52156298020032266431787014754649280499452461532044760665828040879517728539708,
|
||||
33945410025064742625417443716276958550285900443924582459678703741650438534809,
|
||||
42330185455056468790993939554345514151954186453281863597765777627606599578516,
|
||||
4657049000824091386723963460476049183867985168345526464398818750489141737163,
|
||||
21923801997589000370088914236235074435502416056621470668050389849529574106202,
|
||||
15805689248891728058742321832039785423037087284565290950005114696831443231147,
|
||||
45984185687363711365029866793756997560497628108006072393015670720821342880668,
|
||||
39156427118840011190894400331617643276463742427839568112463350872444907680494,
|
||||
17893081445111736451083202165540649827781358816986209263756161212394728333001,
|
||||
36437118588111746025389127729913810175419804691977510411734238734357426423809,
|
||||
48260118028483684631326190969379716083209813670977725322552249653459435387882,
|
||||
40486986020827308332276345571616851806907994309632663940769016980912192516960,
|
||||
35099819227656121544999230187647432362290129526704475429625894785506342902690,
|
||||
27580239951806652383156459031577005530932247841092109348006802746879132126644,
|
||||
23271341957819036356728305748625419304831156372249949335195015298360923297133,
|
||||
42515055996716749819345238125802133364043851479046925751568447538867534641232,
|
||||
28714009840464082058245378340345146078016662568993921795177048501158035190256,
|
||||
1111216851713657365641977385220157904693120725668727899264987734176843126786,
|
||||
34412967565386968523345579224490035779382635330951678114018655424976710134202,
|
||||
42139998487524182591996890653589805817774015986629937281031206233447268328582,
|
||||
21691713516840627241183176855164665841929652491546118303064101066110796188953,
|
||||
27652419528236676047196125264032473043981854331278230828308077279941937298620,
|
||||
31211569185747715573358506785717075277547885839683427922002064474550453938720,
|
||||
12885686250323264975654813526936397901419023857524625007681452625820802164214,
|
||||
38368208456555528544874775339563689416708041768804542366734634684956870468665,
|
||||
17014127458377497594462762243899040828274799467801458439796258262209705848999,
|
||||
18339473410858561688021816579378042667435599228737095147372090986285098295729,
|
||||
30243070523454822835312974811746059176298060623371243491658504828859436915867,
|
||||
6856623016702194887799030091421067262770379379384975426793372305588238369793,
|
||||
14584928177339868798941696431226120632338622678933396299538143948251685736857,
|
||||
28963568590115676917816187714525023427152141272289632646661816895205441501344,
|
||||
15821449895801494782675541871540375313851597664972871699624592153555269853492,
|
||||
26870110211337166665285488169972107901304782738602697811217352528389112713316,
|
||||
29654640625766553122308126800147704038633411112031981115431401674463728957870,
|
||||
45387771697529877530693987615375947783672003547457057946997587632853767376485,
|
||||
51530073844213986083224257489799416809305283668200085363164553259742628578601,
|
||||
39500637489121678568797859105259741238785871932514496730971686474963916800838,
|
||||
34638632655721665381292046101540251812987268394182233780890406749905123665498,
|
||||
47558773840542513144047273382754220597014222776549583477762891202886304283558,
|
||||
34464683426026223214818536296789584915103714217643035512538086729011924346398,
|
||||
50661423324933414471281644339552326226886136985713868196538700335246118227921,
|
||||
16026951337367383175610820246210183497734025720194433489132017234538604936414,
|
||||
33572475268799564642745000649407837861228346301126684294541252715366099579094,
|
||||
26220434981437976873498592303656146371158505657662010285451539733034399969825,
|
||||
31040488125858696173362986090795905945928951823554908571888900564555975057860,
|
||||
47286385036886749775224009536390346046643937618292722852399698152345906543537,
|
||||
20950917282535983122464307959293663918938997314569186126689031705635737272062,
|
||||
16685712499755301665281386819771726363157372904949135525550583883571962834528,
|
||||
18683291445525541017294795892345078328382688847480507122165708511223740177458,
|
||||
2608268839331669212463985078421319322001352992807108968314090990777368891770,
|
||||
40037105172855926626375817902131326490267684706159606232991633054381953553026,
|
||||
21626330967116418140505001603028197974177240574915763170077069271066169546158,
|
||||
35330469786033362269122965704661462637931218147681429112041541870602933338162,
|
||||
7959740499179483922969783988740981409045430979967212583073048384801003055527
|
||||
];
|
||||
}
|
||||
@ -1,80 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
function round_constant_2_to_1() {
|
||||
return
|
||||
[
|
||||
44510337639712444877093863969199054965277800588455612249278638908194748645831,
|
||||
21803715039317278198490310228838761820084178670568647145430631061363562182159,
|
||||
7624865858307587153533893753671854337113466346291121078558552645350285711947,
|
||||
40816250157678830542785454550323790288400761867270997552332922267166370848099,
|
||||
26700489303136047462599262740180012654857443933973506452655094204874268181798,
|
||||
29300041198680547975810813644545348954050411371551740473502764872245855641482,
|
||||
26494260871076350781917504826961109818301921647993891506179327799406892257760,
|
||||
51471943067203395853539598076816386277188697473371359746626216561944728278869,
|
||||
48874150250826827063647140518997592549563417409147246235831213929889330889464,
|
||||
4957296567799842922524759318027693610815701909959689401077625970883603151110,
|
||||
49787130886622940646628207982474849305464467960406760686521606845929813913147,
|
||||
38626507234346048667761615866199783635070759234617387640403950557591257611930,
|
||||
43672937506493322470130890010227422460105683953151094688032165492686807529714,
|
||||
10282858088808039236495153687326481750629167926398528104702176163827531439774,
|
||||
5929373583590601619353793840106929273025491048347772550388315300478156302480,
|
||||
40523767159781096993564794726793344971416282562716017669035314514589021856544,
|
||||
35087653160263082011551011896785452178273871331090954735353760094574180797326,
|
||||
44066134544197993553720315073514236799698542066082224906667320314729128689851,
|
||||
46811190561503483095087189032015959148465356044838419985597715002375968521789,
|
||||
35502138198479058392251639631217384470706251578088034693745546686222031522574,
|
||||
3011951966042824356793101436014075881633742606023423824609791334873649401619,
|
||||
36441783079799715976603149530703751751672873737838939240893549516900746063885,
|
||||
5949000965032854376013985161729805610095473216976505768565157587449663833146,
|
||||
39334547265154726054631299624100840161191136653442409769156478840344483284117,
|
||||
44407194440944549422962884120864337491414458688079798116475114348830479824132,
|
||||
17726376508115223453307205134714318843193912409715438117420622264717671262663,
|
||||
756868613004458973360577644537468651009832005811964377612175868388980341238,
|
||||
3421893741771938128946389260799798658478598753415463644298734220953059738355,
|
||||
13293243933107737951928282334791569607692876620282367672054893180625816893632,
|
||||
11906453198605884256628058547608350794281153234160543833653104246224561572116,
|
||||
41007993900563419378450318427807675773574107233531791780559911428122060668864,
|
||||
48053112103639043655338341411293547635466618118313162578053483741000954697443,
|
||||
32234194819559922425974652761643838211443296225838831687358769666643041225472,
|
||||
48939529425812404248175324082406620877605698116805848434311747711965735603142,
|
||||
23172302197508009638107441698229967178757578829167657081073715837516157038684,
|
||||
26828245904250884987904133111377098838723772557669646848196202419087853870872,
|
||||
36025164071480125389137319620343252251920437049927443652919962965645042660420,
|
||||
42147865145919705097445974287709456827305052297675196211654971979806749888911,
|
||||
20585606416170880487041307637777839232517038894653375498347934603702403525799,
|
||||
1047663270527934381838445994762652910090839507177449076034186708210288801902,
|
||||
49864990265274912108645272682223261996354786042911445790248422528668444967688,
|
||||
20274910123179255493744356413243132767746258718293295072669857132542604950741,
|
||||
39934722872842035804029775488645871956511886709858512717725127998627130523912,
|
||||
33295937568441654166303959882114891655347924209941192993151592385097862772126,
|
||||
39198754144978337534654702520273605486297255614756323128663775493042981926264,
|
||||
48114214484211668830722398263059235215883885642960292320018016482221617479308,
|
||||
20857205525756474383857323509517945359548153106777905032259140536596758842151,
|
||||
20481512031474492331394869498229505122694442073123511672315331466779200648987,
|
||||
5512348932066875222255592673449822544023582557729178288775446420395599163714,
|
||||
14748707870289380337081091822758247948394420380976550635416667891847265434773,
|
||||
20722592968207591585193709289557966995643707360519106502308701025990663556112,
|
||||
30345071158541998337681526950804671230825251993252779307899796752848528236301,
|
||||
37998633152333475045376762610205951441947316428701472139959038991258723083573,
|
||||
25187075483245106412039082847435291293567789993240499080077480139071082713811,
|
||||
19421269742609173994970218921590288196829015512476170234735579602917648585528,
|
||||
44645626649350902490681022627010246390651823839290377812847048196342039743308,
|
||||
38015410591674700109176981164929629504879929166582206795827935147005325179107,
|
||||
15907673084411204300870039215095416489657280867726923876605554605918361454411,
|
||||
4839910768263945909615643698821897421248623201436406727882801614226282796736,
|
||||
11993166323725114372511567048380837525145267539902083755578961856890086640616,
|
||||
13920948384274828210917386586592591296235909076917892178237942711445546791673,
|
||||
890670937435713979056767019654860866935017937714294844928044822115961948695,
|
||||
17228860181078068965008756660486864527552317469394243328944319614877053158985,
|
||||
10077644153064320976006893555780056518106113458749153233744229760482343163199,
|
||||
49940012233787551970719440300197866554675665187348390484098206972627022147562,
|
||||
46156268877611784805956766593634373731938578230585206172333523828368963221701,
|
||||
22953533088186447995354081903847946065608888217162100116127853233026059928601,
|
||||
52274456635025394989373456728632213614198023598074828050923870917877714774032,
|
||||
10763107301772445560209819564880953581415947909035345171575074311681161298071,
|
||||
18925434003927090811791086956853651992753402455627802833236246367412669605539,
|
||||
44640541969065703218376218137336488126193962189090743983027473909004591005110,
|
||||
6325804276918590364991192431609508508777152352802958405080031341778877821773
|
||||
];
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
function round_constant_4_to_1() {
|
||||
return
|
||||
[
|
||||
11865901593870436687704696210307853465124332568266803587887584059192277437537,
|
||||
37413344849675497106163505103761203874617077416461933389729149896951619083615,
|
||||
32493856687297537788073517556470839888070933486712636845483468275561142904504,
|
||||
8106572321306448561272383558012749963748358844705299406391447161298410877832,
|
||||
11707331945334514286120137391947350087632085623772869951863164361695922976568,
|
||||
50176353669915139758684707864014381736527453065793678083699453978150986704353,
|
||||
7614231165138437703715796351400512419034157550777684039873810826440625723695,
|
||||
17108745804308684637964438487237723214541645477949369557189249702220750722331,
|
||||
28482709556494724328894800736802198653800073555798724636385135549439085356742,
|
||||
22084621272529558534346674593668266856649195963035162420257478396107381285157,
|
||||
11065046937453971018193111360820446155970823623967390073553725256595768408791,
|
||||
20163386569362559253936962862374791389308839238220230985809310822791529262025,
|
||||
3941572053547598429065422950522133819874343789089916995553450661687375302109,
|
||||
26478286544099137612981910043301624023925078357447813396543283503388535703096,
|
||||
20695873604353009531429015276900191600064214090812802713214397507580078182919,
|
||||
13125722302273298866746961565666978849814465870768123336569424431819752980076,
|
||||
36198064501926046106576802008779486932990788729159233810880339338049275796987,
|
||||
44304460846758155168737768840994398685118878625607355725968797162919830864102,
|
||||
33427295080737122973704388239917504856466726697805464799279074730831006493899,
|
||||
33676819385378678616140345579679379172852136878360832374035200947147349341877,
|
||||
44698579309865383047943970651850256651158236406641741596599260270592257060333,
|
||||
9785548396072733556484927856146778907814788851086349315764873426432645263872,
|
||||
13443943788901083053739342733252043423900693132812974385986650498262359453435,
|
||||
50643729733611061821734405325096960434556494526582143101458996741611494836986,
|
||||
9762302758250004682914036756566790454206292929079802149918241419991743778078,
|
||||
19475373737975172049750799347581927313285945820087657933615778552974211829387,
|
||||
26326676308398320579169539788392437654921007121904386041440053251920191437301,
|
||||
33434337088018971767011967694326287068660679954245122268447231545106574191053,
|
||||
21854837019991553667332010956652219921642250105983660108852707854862240766704,
|
||||
1855873836256370364169888814967543928768577071445146807885001909257610924575,
|
||||
48105724357874736702308498318239595022868478610964925776544998873327877770469,
|
||||
6893757226114776013992120610353413647048965744053221939747330482283347049271,
|
||||
49492933790401867565879330847407697876101917412920943837692305231776568086150,
|
||||
43522959518323197786977932091172575965428037444858136419745890338308804820810,
|
||||
39369220628770987071776708725487093142438968678975788148890686830600891659237,
|
||||
24332002500271167754445178113059124234684848763578719088484322891936508359054,
|
||||
32863475623207582419161401899951874256189430526558709698459253237664899579477,
|
||||
8315390532973093090228198037973187268458339671135900692256692995983001224287,
|
||||
41596164941281344945126840056611498785955123869980989807278169650894369778621,
|
||||
41140021013127548285923961611241892352480288807646515822914427245468443615449,
|
||||
42624333566444295089232230699974262280460377983015559040916764999567317327294,
|
||||
29425841969458336716648866633284898031574592123216791821970989517602546368463,
|
||||
20194832349178074328255630030474794676357522951312816945265283318496141911576,
|
||||
33508834389330212986852784163678812323448884912646004437785005736522859730449,
|
||||
20197489266521008707527755143868210833027985912465941510937472218208331469324,
|
||||
38189796622106345878699238475711002255025750905901925248625120562682573353793,
|
||||
48437331749916394313065146750618123382683254942785601073233866557242834888501,
|
||||
34815884667490928168338620954175830688114531237099462583592020572423301193334,
|
||||
1316079587764339149090919530288539945185249635387918305928554726824292235069,
|
||||
33564480841331620167847153616337187248054503582700661803825728035418602546478,
|
||||
4635634898381888421672273828316335969974599848444510316738469345444620659008,
|
||||
8644506076646842294589324870931361199184791348209582052726445382015132439419,
|
||||
39498585060657083972778194861599167626335350278223243726925173218749695943806,
|
||||
42901602831339057007425445486193581840749112246589631302873671293308101878875,
|
||||
20119933204882102974459031584507100339282292349398588923453836079377072829543,
|
||||
7917862289043363038204972116125424279857433068189510615392330392863075948512,
|
||||
41284417024025222157952919191031968108126105524670279472881067727309802924938,
|
||||
11213861995768467857413038001306057240793870929626059934261458727946548965379,
|
||||
2291742710611132809700323762125675349484016058554275673428643410085506076100,
|
||||
30099159053997341705317995418169313532098300934328131162175924134794709943047,
|
||||
447035513285578307783519781307142266645679652807941291454847780415896684065,
|
||||
19941446202184504378547837635870560393064630187876613630546846906393007677289,
|
||||
7595261399959684629699197426920893479848768772071384660164934610968891053864,
|
||||
51598580281806900142260694365187051410317675046136337884836978415482902327015,
|
||||
12450848281586712352554721829724230078424064515794153380314705783292880037478,
|
||||
5237102499670441785007944785581992844697685968922355014280712201430686167152,
|
||||
1412524057853628881005630586377727487233247150373319518286783509614859257068,
|
||||
38519766408760192821848550196157518411386556623071006612683448412823634200875,
|
||||
11338671486975802181674275776989710780888734229624346786700048285586675342901,
|
||||
23124572501783393477231165425714476214042723292141825213493635111951207504070,
|
||||
21528356110015199451243279738115385806356940590132503530639630620611521954326,
|
||||
6284174238932569340060925799940162325946442751185026413727709496271066916876,
|
||||
48373517651545249281510690416218268384343400250317171450103976311090286221260,
|
||||
27752440147182328733098243645400559151338503658043397110598417983425635093551,
|
||||
43156725395743020846958899706072234263962738024394096815001388170789961679788,
|
||||
48906049704561774201639151262665470255437206145980347197443063657678740507943,
|
||||
24918160465086526594937065443815615610757370328053649165018481775513828479869,
|
||||
36462368786443951186110721729238677880688318912401935278190656741197184273952,
|
||||
37367696075403883562827939745268661270924157618310868295845006320225084994632,
|
||||
42130603320119794983803262970740129474583503116320676437504579920473229006778,
|
||||
12096038367976885628335054904138821822550042039079703385879844461517464118581,
|
||||
34671362090033614505367959844073659507869267381932134573786004532584171425818,
|
||||
15908652423714359894720614650322760756461828514699821946843077879932200328081,
|
||||
7518568119601342737128460613704294443674406422237476295695786631549469567412,
|
||||
33513737101700389003254558060695049730922342329295390135821890558696123720054,
|
||||
49765425774819103826723198731734445691737353182147628471479513204868044796119,
|
||||
48731721046471530891684818884908827036844194399863789073273030545326532602503,
|
||||
1994879948378542466338304292753049990663872919840272992167645879411261807091
|
||||
];
|
||||
}
|
||||
55
circom_circuits/hash_bn/merkle.circom
Normal file
55
circom_circuits/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
circom_circuits/hash_bn/poseidon2_hash.circom
Normal file
19
circom_circuits/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
circom_circuits/hash_bn/poseidon2_perm.circom
Normal file
217
circom_circuits/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
circom_circuits/hash_bn/poseidon2_sponge.circom
Normal file
123
circom_circuits/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
circom_circuits/ledger/notes.circom
Normal file
30
circom_circuits/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;
|
||||
}
|
||||
80
circom_circuits/misc/comparator.circom
Normal file
80
circom_circuits/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
circom_circuits/misc/constants.circom
Normal file
67
circom_circuits/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;
|
||||
}
|
||||
1
circom_circuits/rapidsnark
Submodule
1
circom_circuits/rapidsnark
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 998383787ee86bcb6bfb8741e9a638d203c08eae
|
||||
@ -1,103 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_4_to_1_Jubjub.circom";
|
||||
|
||||
template coefficient_hash(){
|
||||
signal input coefficients[2048];
|
||||
|
||||
signal output hash;
|
||||
|
||||
component hasher[136];
|
||||
hasher[0] = permutation_16_to_1();
|
||||
hasher[0].in[0] <== 0;
|
||||
for(var i = 1; i<16; i++){
|
||||
hasher[0].in[i] <== coefficients[i-1];
|
||||
}
|
||||
|
||||
|
||||
for(var i = 1; i<136; i++){
|
||||
hasher[i] = permutation_16_to_1();
|
||||
hasher[i].in[0] <== hasher[i-1].out[0];
|
||||
for(var j = 1; j<16; j++){
|
||||
hasher[i].in[j] <== hasher[i-1].out[j] + coefficients[15*i+j-1];
|
||||
}
|
||||
}
|
||||
|
||||
component final_hasher = hash_16_to_1();
|
||||
for (var i =0; i<8; i++){
|
||||
final_hasher.in[i] <== hasher[135].out[i] + coefficients[2040+i];
|
||||
}
|
||||
for (var i =8; i<16; i++){
|
||||
final_hasher.in[i] <== hasher[135].out[i];
|
||||
}
|
||||
|
||||
hash <== final_hasher.out;
|
||||
}
|
||||
|
||||
template drawn_random_point(){
|
||||
signal input da_commitment[2];
|
||||
signal input hash_of_data;
|
||||
|
||||
signal output x_0;
|
||||
|
||||
component final_hasher = hash_4_to_1();
|
||||
|
||||
final_hasher.in[0] <== 0;
|
||||
final_hasher.in[1] <== da_commitment[0];
|
||||
final_hasher.in[2] <== da_commitment[1];
|
||||
final_hasher.in[3] <== hash_of_data;
|
||||
|
||||
x_0 <== final_hasher.out;
|
||||
}
|
||||
|
||||
template evaluate_polynomial(){
|
||||
signal input coefficients[2048];
|
||||
signal input evaluation_point;
|
||||
|
||||
signal output result;
|
||||
|
||||
signal intermediate_values[2046];
|
||||
intermediate_values[2045] <== coefficients[2047] * evaluation_point + coefficients[2046];
|
||||
for(var i = 2044; i >= 0; i--){
|
||||
intermediate_values[i] <== coefficients[i + 1] + intermediate_values[i+1] * evaluation_point;
|
||||
}
|
||||
|
||||
result <== coefficients[0] + intermediate_values[0] * evaluation_point;
|
||||
}
|
||||
|
||||
template proof_of_equivalence(){
|
||||
signal input coefficients[2048];
|
||||
signal input da_commitment[2];
|
||||
|
||||
signal output x_0;
|
||||
signal output y_0;
|
||||
signal output coefficients_hash;
|
||||
|
||||
//Hash of the coefficients
|
||||
component coefficient_hasher = coefficient_hash();
|
||||
for(var i = 0; i<2048; i++){
|
||||
coefficient_hasher.coefficients[i] <== coefficients[i];
|
||||
}
|
||||
coefficients_hash <== coefficient_hasher.hash;
|
||||
|
||||
//Hash the coefficient hash with the da_commitment
|
||||
component point_drawer = drawn_random_point();
|
||||
point_drawer.da_commitment[0] <== da_commitment[0];
|
||||
point_drawer.da_commitment[1] <== da_commitment[1];
|
||||
point_drawer.hash_of_data <== coefficients_hash;
|
||||
x_0 <== point_drawer.x_0;
|
||||
|
||||
//Evaluate the polynomial at x_0
|
||||
component evaluator = evaluate_polynomial();
|
||||
evaluator.evaluation_point <== x_0;
|
||||
for(var i =0; i<2048; i++){
|
||||
evaluator.coefficients[i] <== coefficients[i];
|
||||
}
|
||||
|
||||
y_0 <== evaluator.result;
|
||||
}
|
||||
|
||||
|
||||
component main {public [da_commitment]} = proof_of_equivalence();
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,301 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template BLSNum2Bits_strict() {
|
||||
signal input in;
|
||||
signal output out[255];
|
||||
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528); // -1 - 2**254 (p-1 without its first bit)
|
||||
component n2b = Num2Bits(255);
|
||||
in ==> n2b.in;
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
n2b.out[i] ==> out[i];
|
||||
if(i != 0){
|
||||
n2b.out[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * (n2b.out[0]) === 0; //must be zero exept if the first bit is 0 => then in is on 254 bits and p-1 on 255
|
||||
}
|
||||
|
||||
template BLSBits2Num_strict() {
|
||||
signal input in[255];
|
||||
signal output out;
|
||||
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528);
|
||||
component b2n = Bits2Num(255);
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
in[i] ==> b2n.in[i];
|
||||
if(i != 0){
|
||||
in[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * in[0] === 0;
|
||||
|
||||
b2n.out ==> out;
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template check_lottery(){
|
||||
signal input epoch_nonce;
|
||||
signal input slot_number;
|
||||
signal input t0;
|
||||
signal input t1; // The precomputed threshold values
|
||||
|
||||
signal input constraints;
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
|
||||
component hash = hash_16_to_1();
|
||||
|
||||
//The b"lead" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 1818583396;
|
||||
|
||||
hash.in[1] <== epoch_nonce;
|
||||
hash.in[2] <== slot_number;
|
||||
hash.in[3] <== constraints;
|
||||
hash.in[4] <== value;
|
||||
hash.in[5] <== unit;
|
||||
hash.in[6] <== state;
|
||||
hash.in[7] <== note_nonce;
|
||||
hash.in[8] <== nullifier_secret_key;
|
||||
hash.in[9] <== randomness;
|
||||
for(var i=10; i<16; i++){
|
||||
hash.in[i] <== 0;
|
||||
}
|
||||
|
||||
// As p-1 is divisible by 4, if X follows a uniform distribution between 0 and p-1
|
||||
// Y = X % (p-1)/4 nearly follows a uniform distribution between 0 and ((p-1)/4)-1 (exept that 0 has 20% more chance to appear than another element which is negligible)
|
||||
// So we transform the hash of a maximum of 255 to a hash of a maximum of 253 bits by taking its modulo
|
||||
// (p-1)/4 = 13108968793781547619861935127046491459422638125131909455650914674984645296128
|
||||
// TODO: check this part to ensure it is secure
|
||||
signal quotient;
|
||||
signal ticket;
|
||||
quotient <-- hash.out \ 13108968793781547619861935127046491459422638125131909455650914674984645296128;
|
||||
ticket <-- hash.out % 13108968793781547619861935127046491459422638125131909455650914674984645296128;
|
||||
|
||||
//check that quotient is 0,1,2 or 3
|
||||
signal check_quotient[2];
|
||||
check_quotient[0] <== quotient * (1-quotient);
|
||||
check_quotient[1] <== (2-quotient)*(3-quotient);
|
||||
check_quotient[0] * check_quotient[1] === 0;
|
||||
|
||||
//check the correctness of the division
|
||||
ticket + quotient * 13108968793781547619861935127046491459422638125131909455650914674984645296128 === hash.out;
|
||||
|
||||
//check that the ticket is less than the divisor
|
||||
component isLess = CompConstant(13108968793781547619861935127046491459422638125131909455650914674984645296128);
|
||||
component bitifier = BLSNum2Bits_strict();
|
||||
|
||||
bitifier.in <== ticket;
|
||||
bitifier.out[254] === 0;
|
||||
for(var i=0; i<254; i++){
|
||||
isLess.in[i] <== bitifier.out[i];
|
||||
}
|
||||
isLess.out === 0;
|
||||
|
||||
|
||||
|
||||
// Compute the threshold
|
||||
signal intermediate_value;
|
||||
signal threshold;
|
||||
intermediate_value <== t0 + t1 * value;
|
||||
threshold <== intermediate_value * value;
|
||||
|
||||
// Ensure that the ticket is winning
|
||||
component isLess2 = BLSLessThan(253);
|
||||
|
||||
isLess2.in[0] <== ticket;
|
||||
isLess2.in[1] <== threshold;
|
||||
isLess2.out === 1;
|
||||
}
|
||||
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template commitment_computer(){ // TODO: ensure all field are hash
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input leaf; //The note commitment
|
||||
signal input root; //The root of the Merkle Tree (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32]; //Complementary hashes
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = hash_2_to_1();
|
||||
}
|
||||
|
||||
hash[0].in[0] <== leaf - index[31] * (leaf - node[0]);
|
||||
hash[0].in[1] <== node[0] - index[31] * (node[0] - leaf);
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
hash[i].in[0] <== hash[i-1].out - index[31-i] * (hash[i-1].out - node[i]);
|
||||
hash[i].in[1] <== node[i] - index[31-i] * (node[i] - hash[i-1].out);
|
||||
}
|
||||
|
||||
root === hash[31].out;
|
||||
|
||||
}
|
||||
|
||||
template anemoi_proof_of_leadership(){
|
||||
signal input epoch_nonce; //F_p (BLS12-381 scalar field)
|
||||
signal input slot_number; //F_p (BLS12-381 scalar field)
|
||||
signal input t0; // Precomputed threshold elements in F_p
|
||||
signal input t1;
|
||||
signal input commitments_root;
|
||||
|
||||
// Note variables
|
||||
signal input constraints; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input nodes[32]; //Merkle proof of the commitment
|
||||
|
||||
signal output nullifier;
|
||||
signal output updated_commiment;
|
||||
|
||||
|
||||
// Check that index inputs are indeed bits
|
||||
component bit_checker = check_bits(32);
|
||||
for(var i=0; i<32; i++){
|
||||
bit_checker.bits[i] <== index[i];
|
||||
}
|
||||
|
||||
// Check that r < threshold
|
||||
component lottery_checker = check_lottery();
|
||||
lottery_checker.epoch_nonce <== epoch_nonce;
|
||||
lottery_checker.slot_number <== slot_number;
|
||||
lottery_checker.t0 <== t0;
|
||||
lottery_checker.t1 <== t1;
|
||||
lottery_checker.constraints <== constraints;
|
||||
lottery_checker.value <== value;
|
||||
lottery_checker.unit <== unit;
|
||||
lottery_checker.state <== state;
|
||||
lottery_checker.note_nonce <== note_nonce;
|
||||
lottery_checker.nullifier_secret_key <== nullifier_secret_key;
|
||||
lottery_checker.randomness <== randomness;
|
||||
|
||||
|
||||
// Compute the note commitment
|
||||
component note_committer = commitment_computer();
|
||||
note_committer.note_nonce <== note_nonce;
|
||||
note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer.value <== value;
|
||||
|
||||
// Check the commitment membership
|
||||
component membership_checker = membership_checker();
|
||||
membership_checker.leaf <== note_committer.commitment;
|
||||
membership_checker.root <== commitments_root;
|
||||
for(var i =0; i<32; i++){
|
||||
membership_checker.index[i] <== index[i];
|
||||
membership_checker.node[i] <== nodes[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the note nullifier
|
||||
component nullifier_computer = nullifier_computer();
|
||||
nullifier_computer.note_nonce <== note_nonce;
|
||||
nullifier_computer.nullifier_secret_key <== nullifier_secret_key;
|
||||
nullifier_computer.value <== value;
|
||||
nullifier <== nullifier_computer.nullifier;
|
||||
|
||||
|
||||
// Compute the evolved nonce
|
||||
component nonce_updater = nonce_updater();
|
||||
nonce_updater.note_nonce <== note_nonce;
|
||||
nonce_updater.nullifier_secret_key <== nullifier_secret_key;
|
||||
|
||||
|
||||
// Compute the new note commitment
|
||||
component updated_note_committer = commitment_computer();
|
||||
updated_note_committer.note_nonce <== nonce_updater.updated_nonce;
|
||||
updated_note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer.value <== value;
|
||||
updated_commiment <== updated_note_committer.commitment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = anemoi_proof_of_leadership();
|
||||
@ -1,317 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/sha256/sha256.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template BLSNum2Bits_strict() {
|
||||
signal input in;
|
||||
signal output out[255];
|
||||
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528); // -1 - 2**254 (p-1 without its first bit)
|
||||
component n2b = Num2Bits(255);
|
||||
in ==> n2b.in;
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
n2b.out[i] ==> out[i];
|
||||
if(i != 0){
|
||||
n2b.out[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * (n2b.out[0]) === 0; //must be zero exept if the first bit is 0 => then in is on 254 bits and p-1 on 255
|
||||
}
|
||||
|
||||
template BLSBits2Num_strict() {
|
||||
signal input in[255];
|
||||
signal output out;
|
||||
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528);
|
||||
component b2n = Bits2Num(255);
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
in[i] ==> b2n.in[i];
|
||||
if(i != 0){
|
||||
in[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * in[0] === 0;
|
||||
|
||||
b2n.out ==> out;
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template check_lottery(){
|
||||
signal input epoch_nonce;
|
||||
signal input slot_number;
|
||||
signal input t0;
|
||||
signal input t1; // The precomputed threshold values
|
||||
|
||||
signal input constraints;
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
|
||||
component hash = Sha256(2336);
|
||||
component bitifier[9];
|
||||
for(var i=0; i<9; i++){
|
||||
bitifier[i] = BLSNum2Bits_strict();
|
||||
}
|
||||
bitifier[0].in <== epoch_nonce;
|
||||
bitifier[1].in <== slot_number;
|
||||
bitifier[2].in <== constraints;
|
||||
bitifier[3].in <== value;
|
||||
bitifier[4].in <== unit;
|
||||
bitifier[5].in <== state;
|
||||
bitifier[6].in <== note_nonce;
|
||||
bitifier[7].in <== nullifier_secret_key;
|
||||
bitifier[8].in <== randomness;
|
||||
|
||||
//The b"lead" Tag in bits with big endian order
|
||||
hash.in[0] <== 0;
|
||||
hash.in[1] <== 1;
|
||||
hash.in[2] <== 1;
|
||||
hash.in[3] <== 0;
|
||||
hash.in[4] <== 1;
|
||||
hash.in[5] <== 1;
|
||||
hash.in[6] <== 0;
|
||||
hash.in[7] <== 0;
|
||||
hash.in[8] <== 0;
|
||||
hash.in[9] <== 1;
|
||||
hash.in[10] <== 1;
|
||||
hash.in[11] <== 0;
|
||||
hash.in[12] <== 0;
|
||||
hash.in[13] <== 1;
|
||||
hash.in[14] <== 0;
|
||||
hash.in[15] <== 1;
|
||||
hash.in[16] <== 0;
|
||||
hash.in[17] <== 1;
|
||||
hash.in[18] <== 1;
|
||||
hash.in[19] <== 0;
|
||||
hash.in[20] <== 0;
|
||||
hash.in[21] <== 0;
|
||||
hash.in[22] <== 0;
|
||||
hash.in[23] <== 1;
|
||||
hash.in[24] <== 0;
|
||||
hash.in[25] <== 1;
|
||||
hash.in[26] <== 1;
|
||||
hash.in[27] <== 0;
|
||||
hash.in[28] <== 0;
|
||||
hash.in[29] <== 1;
|
||||
hash.in[30] <== 0;
|
||||
hash.in[31] <== 0;
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
for(var j=0; j<9; j++){
|
||||
if(i != 0){
|
||||
hash.in[32+256*j+i] <== bitifier[j].out[255-i];
|
||||
} else {
|
||||
hash.in[32+256*j] <== 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component intifier = Bits2Num(253); //Because if the scalar field is 255 bits, we support every number of 254 bits (not all of 255) and we can only compare numbers of 253 bits since we need 1 bit for sign.
|
||||
|
||||
for(var i=0; i<253; i++){
|
||||
intifier.in[i] <== hash.out[253-i];
|
||||
}
|
||||
|
||||
// Compute the threshold
|
||||
signal intermediate_value;
|
||||
signal threshold;
|
||||
intermediate_value <== t0 + t1 * value;
|
||||
threshold <== intermediate_value * value;
|
||||
|
||||
// Ensure that the ticket is winning
|
||||
component isLess2 = BLSLessThan(253);
|
||||
|
||||
isLess2.in[0] <== intifier.out;
|
||||
isLess2.in[1] <== threshold;
|
||||
isLess2.out === 1;
|
||||
}
|
||||
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template commitment_computer(){ // TODO: ensure all field are hash
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input leaf; //The note commitment
|
||||
signal input root; //The root of the Merkle Tree (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32]; //Complementary hashes
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = hash_2_to_1();
|
||||
}
|
||||
|
||||
hash[0].in[0] <== leaf - index[31] * (leaf - node[0]);
|
||||
hash[0].in[1] <== node[0] - index[31] * (node[0] - leaf);
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
hash[i].in[0] <== hash[i-1].out - index[31-i] * (hash[i-1].out - node[i]);
|
||||
hash[i].in[1] <== node[i] - index[31-i] * (node[i] - hash[i-1].out);
|
||||
}
|
||||
|
||||
root === hash[31].out;
|
||||
|
||||
}
|
||||
|
||||
template anemoi_sha_proof_of_leadership(){
|
||||
signal input epoch_nonce; //F_p (BLS12-381 scalar field)
|
||||
signal input slot_number; //F_p (BLS12-381 scalar field)
|
||||
signal input t0; // Precomputed threshold elements in F_p
|
||||
signal input t1;
|
||||
signal input commitments_root;
|
||||
|
||||
// Note variables
|
||||
signal input constraints; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input nodes[32]; //Merkle proof of the commitment
|
||||
|
||||
signal output nullifier;
|
||||
signal output updated_commiment;
|
||||
|
||||
|
||||
// Check that index inputs are indeed bits
|
||||
component bit_checker = check_bits(32);
|
||||
for(var i=0; i<32; i++){
|
||||
bit_checker.bits[i] <== index[i];
|
||||
}
|
||||
|
||||
// Check that r < threshold
|
||||
component lottery_checker = check_lottery();
|
||||
lottery_checker.epoch_nonce <== epoch_nonce;
|
||||
lottery_checker.slot_number <== slot_number;
|
||||
lottery_checker.t0 <== t0;
|
||||
lottery_checker.t1 <== t1;
|
||||
lottery_checker.constraints <== constraints;
|
||||
lottery_checker.value <== value;
|
||||
lottery_checker.unit <== unit;
|
||||
lottery_checker.state <== state;
|
||||
lottery_checker.note_nonce <== note_nonce;
|
||||
lottery_checker.nullifier_secret_key <== nullifier_secret_key;
|
||||
lottery_checker.randomness <== randomness;
|
||||
|
||||
|
||||
// Compute the note commitment
|
||||
component note_committer = commitment_computer();
|
||||
note_committer.note_nonce <== note_nonce;
|
||||
note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer.value <== value;
|
||||
|
||||
// Check the commitment membership
|
||||
component membership_checker = membership_checker();
|
||||
membership_checker.leaf <== note_committer.commitment;
|
||||
membership_checker.root <== commitments_root;
|
||||
for(var i =0; i<32; i++){
|
||||
membership_checker.index[i] <== index[i];
|
||||
membership_checker.node[i] <== nodes[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the note nullifier
|
||||
component nullifier_computer = nullifier_computer();
|
||||
nullifier_computer.note_nonce <== note_nonce;
|
||||
nullifier_computer.nullifier_secret_key <== nullifier_secret_key;
|
||||
nullifier_computer.value <== value;
|
||||
nullifier <== nullifier_computer.nullifier;
|
||||
|
||||
|
||||
// Compute the evolved nonce
|
||||
component nonce_updater = nonce_updater();
|
||||
nonce_updater.note_nonce <== note_nonce;
|
||||
nonce_updater.nullifier_secret_key <== nullifier_secret_key;
|
||||
|
||||
|
||||
// Compute the new note commitment
|
||||
component updated_note_committer = commitment_computer();
|
||||
updated_note_committer.note_nonce <== nonce_updater.updated_nonce;
|
||||
updated_note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer.value <== value;
|
||||
updated_commiment <== updated_note_committer.commitment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = anemoi_sha_proof_of_leadership();
|
||||
@ -1,301 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template BLSNum2Bits_strict() {
|
||||
signal input in;
|
||||
signal output out[255];
|
||||
|
||||
// Ensure that out is lower than p
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528); // -1 - 2**254 (p-1 without its first bit)
|
||||
component n2b = Num2Bits(255);
|
||||
in ==> n2b.in;
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
n2b.out[i] ==> out[i];
|
||||
if(i != 0){
|
||||
n2b.out[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * (n2b.out[0]) === 0; //must be zero exept if the first bit is 0 => then in is on 254 bits and p-1 on 255
|
||||
}
|
||||
|
||||
template BLSBits2Num_strict() {
|
||||
signal input in[255];
|
||||
signal output out;
|
||||
//ensure that in is not greater than p
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528);
|
||||
component b2n = Bits2Num(255);
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
in[i] ==> b2n.in[i];
|
||||
if(i != 0){
|
||||
in[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * in[0] === 0;
|
||||
|
||||
b2n.out ==> out;
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template check_lottery(){
|
||||
signal input epoch_nonce;
|
||||
signal input slot_number;
|
||||
signal input t0;
|
||||
signal input t1; // The precomputed threshold values
|
||||
|
||||
signal input constraints;
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
|
||||
component hash = hash_16_to_1();
|
||||
|
||||
//The b"lead" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 1818583396;
|
||||
|
||||
hash.in[1] <== epoch_nonce;
|
||||
hash.in[2] <== slot_number;
|
||||
hash.in[3] <== constraints;
|
||||
hash.in[4] <== value;
|
||||
hash.in[5] <== unit;
|
||||
hash.in[6] <== state;
|
||||
hash.in[7] <== note_nonce;
|
||||
hash.in[8] <== nullifier_secret_key;
|
||||
hash.in[9] <== randomness;
|
||||
for(var i=10; i<16; i++){
|
||||
hash.in[i] <== 0;
|
||||
}
|
||||
|
||||
// As p-1 is divisible by 4, if X follows a uniform distribution between 0 and p-1
|
||||
// Y = X % (p-1)/4 nearly follows a uniform distribution between 0 and ((p-1)/4)-1 (exept that 0 has 20% more chance to appear than another element which is negligible)
|
||||
// So we transform the hash of a maximum of 255 to a hash of a maximum of 253 bits by taking its modulo
|
||||
// (p-1)/4 = 13108968793781547619861935127046491459422638125131909455650914674984645296128
|
||||
// TODO: check this part to ensure it is secure
|
||||
signal quotient;
|
||||
signal ticket;
|
||||
quotient <-- hash.out \ 13108968793781547619861935127046491459422638125131909455650914674984645296128;
|
||||
ticket <-- hash.out % 13108968793781547619861935127046491459422638125131909455650914674984645296128;
|
||||
|
||||
//check that quotient is 0,1,2 or 3
|
||||
signal check_quotient[2];
|
||||
check_quotient[0] <== quotient * (1-quotient);
|
||||
check_quotient[1] <== (2-quotient)*(3-quotient);
|
||||
check_quotient[0] * check_quotient[1] === 0;
|
||||
|
||||
//check the correctness of the division
|
||||
ticket + quotient * 13108968793781547619861935127046491459422638125131909455650914674984645296128 === hash.out;
|
||||
|
||||
//check that the ticket is less than the divisor
|
||||
component isLess = CompConstant(13108968793781547619861935127046491459422638125131909455650914674984645296128);
|
||||
component bitifier = BLSNum2Bits_strict();
|
||||
|
||||
bitifier.in <== ticket;
|
||||
bitifier.out[254] === 0;
|
||||
for(var i=0; i<254; i++){
|
||||
isLess.in[i] <== bitifier.out[i];
|
||||
}
|
||||
isLess.out === 0;
|
||||
|
||||
|
||||
|
||||
// Compute the threshold
|
||||
signal intermediate_value;
|
||||
signal threshold;
|
||||
intermediate_value <== t0 + t1 * value;
|
||||
threshold <== intermediate_value * value;
|
||||
|
||||
// Ensure that the ticket is indeed 253 bits and that the ticket is winning
|
||||
component isLess2 = BLSLessThan(253);
|
||||
isLess2.in[0] <== ticket;
|
||||
isLess2.in[1] <== threshold;
|
||||
isLess2.out === 1;
|
||||
}
|
||||
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template commitment_computer(){ // TODO: ensure all field are hash
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input leaf; //The note commitment
|
||||
signal input root; //The root of the Merkle Tree (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32]; //Complementary hashes
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = hash_2_to_1();
|
||||
}
|
||||
|
||||
hash[0].in[0] <== leaf - index[31] * (leaf - node[0]);
|
||||
hash[0].in[1] <== node[0] - index[31] * (node[0] - leaf);
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
hash[i].in[0] <== hash[i-1].out - index[31-i] * (hash[i-1].out - node[i]);
|
||||
hash[i].in[1] <== node[i] - index[31-i] * (node[i] - hash[i-1].out);
|
||||
}
|
||||
|
||||
root === hash[31].out;
|
||||
|
||||
}
|
||||
|
||||
template poseidon_proof_of_leadership(){
|
||||
signal input epoch_nonce; //F_p (BLS12-381 scalar field)
|
||||
signal input slot_number; //F_p (BLS12-381 scalar field)
|
||||
signal input t0; // Precomputed threshold elements in F_p
|
||||
signal input t1;
|
||||
signal input commitments_root;
|
||||
|
||||
// Note variables
|
||||
signal input constraints; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input nodes[32]; //Merkle proof of the commitment
|
||||
|
||||
signal output nullifier;
|
||||
signal output updated_commiment;
|
||||
|
||||
|
||||
// Check that index inputs are indeed bits
|
||||
component bit_checker = check_bits(32);
|
||||
for(var i=0; i<32; i++){
|
||||
bit_checker.bits[i] <== index[i];
|
||||
}
|
||||
|
||||
// Check that r < threshold
|
||||
component lottery_checker = check_lottery();
|
||||
lottery_checker.epoch_nonce <== epoch_nonce;
|
||||
lottery_checker.slot_number <== slot_number;
|
||||
lottery_checker.t0 <== t0;
|
||||
lottery_checker.t1 <== t1;
|
||||
lottery_checker.constraints <== constraints;
|
||||
lottery_checker.value <== value;
|
||||
lottery_checker.unit <== unit;
|
||||
lottery_checker.state <== state;
|
||||
lottery_checker.note_nonce <== note_nonce;
|
||||
lottery_checker.nullifier_secret_key <== nullifier_secret_key;
|
||||
lottery_checker.randomness <== randomness;
|
||||
|
||||
|
||||
// Compute the note commitment
|
||||
component note_committer = commitment_computer();
|
||||
note_committer.note_nonce <== note_nonce;
|
||||
note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer.value <== value;
|
||||
|
||||
// Check the commitment membership
|
||||
component membership_checker = membership_checker();
|
||||
membership_checker.leaf <== note_committer.commitment;
|
||||
membership_checker.root <== commitments_root;
|
||||
for(var i =0; i<32; i++){
|
||||
membership_checker.index[i] <== index[i];
|
||||
membership_checker.node[i] <== nodes[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the note nullifier
|
||||
component nullifier_computer = nullifier_computer();
|
||||
nullifier_computer.note_nonce <== note_nonce;
|
||||
nullifier_computer.nullifier_secret_key <== nullifier_secret_key;
|
||||
nullifier_computer.value <== value;
|
||||
nullifier <== nullifier_computer.nullifier;
|
||||
|
||||
|
||||
// Compute the evolved nonce
|
||||
component nonce_updater = nonce_updater();
|
||||
nonce_updater.note_nonce <== note_nonce;
|
||||
nonce_updater.nullifier_secret_key <== nullifier_secret_key;
|
||||
|
||||
|
||||
// Compute the new note commitment
|
||||
component updated_note_committer = commitment_computer();
|
||||
updated_note_committer.note_nonce <== nonce_updater.updated_nonce;
|
||||
updated_note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer.value <== value;
|
||||
updated_commiment <== updated_note_committer.commitment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = poseidon_proof_of_leadership();
|
||||
@ -1,318 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/sha256/sha256.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template BLSNum2Bits_strict() {
|
||||
signal input in;
|
||||
signal output out[255];
|
||||
|
||||
// Ensure that out is lower than p
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528); // -1 - 2**254 (p-1 without its first bit)
|
||||
component n2b = Num2Bits(255);
|
||||
in ==> n2b.in;
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
n2b.out[i] ==> out[i];
|
||||
if(i != 0){
|
||||
n2b.out[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * (n2b.out[0]) === 0; //must be zero exept if the first bit is 0 => then in is on 254 bits and p-1 on 255
|
||||
}
|
||||
|
||||
template BLSBits2Num_strict() {
|
||||
signal input in[255];
|
||||
signal output out;
|
||||
//ensure that in is not greater than p
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528);
|
||||
component b2n = Bits2Num(255);
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
in[i] ==> b2n.in[i];
|
||||
if(i != 0){
|
||||
in[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * in[0] === 0;
|
||||
|
||||
b2n.out ==> out;
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template check_lottery(){
|
||||
signal input epoch_nonce;
|
||||
signal input slot_number;
|
||||
signal input t0;
|
||||
signal input t1; // The precomputed threshold values
|
||||
|
||||
signal input constraints;
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
|
||||
component hash = Sha256(2336);
|
||||
component bitifier[9];
|
||||
for(var i=0; i<9; i++){
|
||||
bitifier[i] = BLSNum2Bits_strict();
|
||||
}
|
||||
bitifier[0].in <== epoch_nonce;
|
||||
bitifier[1].in <== slot_number;
|
||||
bitifier[2].in <== constraints;
|
||||
bitifier[3].in <== value;
|
||||
bitifier[4].in <== unit;
|
||||
bitifier[5].in <== state;
|
||||
bitifier[6].in <== note_nonce;
|
||||
bitifier[7].in <== nullifier_secret_key;
|
||||
bitifier[8].in <== randomness;
|
||||
|
||||
//The b"lead" Tag in bits with big endian order
|
||||
hash.in[0] <== 0;
|
||||
hash.in[1] <== 1;
|
||||
hash.in[2] <== 1;
|
||||
hash.in[3] <== 0;
|
||||
hash.in[4] <== 1;
|
||||
hash.in[5] <== 1;
|
||||
hash.in[6] <== 0;
|
||||
hash.in[7] <== 0;
|
||||
hash.in[8] <== 0;
|
||||
hash.in[9] <== 1;
|
||||
hash.in[10] <== 1;
|
||||
hash.in[11] <== 0;
|
||||
hash.in[12] <== 0;
|
||||
hash.in[13] <== 1;
|
||||
hash.in[14] <== 0;
|
||||
hash.in[15] <== 1;
|
||||
hash.in[16] <== 0;
|
||||
hash.in[17] <== 1;
|
||||
hash.in[18] <== 1;
|
||||
hash.in[19] <== 0;
|
||||
hash.in[20] <== 0;
|
||||
hash.in[21] <== 0;
|
||||
hash.in[22] <== 0;
|
||||
hash.in[23] <== 1;
|
||||
hash.in[24] <== 0;
|
||||
hash.in[25] <== 1;
|
||||
hash.in[26] <== 1;
|
||||
hash.in[27] <== 0;
|
||||
hash.in[28] <== 0;
|
||||
hash.in[29] <== 1;
|
||||
hash.in[30] <== 0;
|
||||
hash.in[31] <== 0;
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
for(var j=0; j<9; j++){
|
||||
if(i != 0){
|
||||
hash.in[32+256*j+i] <== bitifier[j].out[255-i];
|
||||
} else {
|
||||
hash.in[32+256*j] <== 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component intifier = Bits2Num(253); //Because if the scalar field is 255 bits, we support every number of 254 bits (not all of 255) and we can only compare numbers of 253 bits since we need 1 bit for sign.
|
||||
|
||||
for(var i=0; i<253; i++){
|
||||
intifier.in[i] <== hash.out[253-i];
|
||||
}
|
||||
|
||||
// Compute the threshold
|
||||
signal intermediate_value;
|
||||
signal threshold;
|
||||
intermediate_value <== t0 + t1 * value;
|
||||
threshold <== intermediate_value * value;
|
||||
|
||||
// Ensure that the ticket is winning
|
||||
component isLess2 = BLSLessThan(253);
|
||||
|
||||
isLess2.in[0] <== intifier.out;
|
||||
isLess2.in[1] <== threshold;
|
||||
//isLess2.out === 1;
|
||||
}
|
||||
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template commitment_computer(){ // TODO: ensure all field are hash
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input leaf; //The note commitment
|
||||
signal input root; //The root of the Merkle Tree (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32]; //Complementary hashes
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = hash_2_to_1();
|
||||
}
|
||||
|
||||
hash[0].in[0] <== leaf - index[31] * (leaf - node[0]);
|
||||
hash[0].in[1] <== node[0] - index[31] * (node[0] - leaf);
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
hash[i].in[0] <== hash[i-1].out - index[31-i] * (hash[i-1].out - node[i]);
|
||||
hash[i].in[1] <== node[i] - index[31-i] * (node[i] - hash[i-1].out);
|
||||
}
|
||||
|
||||
//root === hash[31].out;
|
||||
|
||||
}
|
||||
|
||||
template poseidon_sha_proof_of_leadership(){
|
||||
signal input epoch_nonce; //F_p (BLS12-381 scalar field)
|
||||
signal input slot_number; //F_p (BLS12-381 scalar field)
|
||||
signal input t0; // Precomputed threshold elements in F_p
|
||||
signal input t1;
|
||||
signal input commitments_root;
|
||||
|
||||
// Note variables
|
||||
signal input constraints; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input randomness;
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input nodes[32]; //Merkle proof of the commitment
|
||||
|
||||
signal output nullifier;
|
||||
signal output updated_commiment;
|
||||
|
||||
|
||||
// Check that index inputs are indeed bits
|
||||
component bit_checker = check_bits(32);
|
||||
for(var i=0; i<32; i++){
|
||||
bit_checker.bits[i] <== index[i];
|
||||
}
|
||||
|
||||
// Check that r < threshold
|
||||
component lottery_checker = check_lottery();
|
||||
lottery_checker.epoch_nonce <== epoch_nonce;
|
||||
lottery_checker.slot_number <== slot_number;
|
||||
lottery_checker.t0 <== t0;
|
||||
lottery_checker.t1 <== t1;
|
||||
lottery_checker.constraints <== constraints;
|
||||
lottery_checker.value <== value;
|
||||
lottery_checker.unit <== unit;
|
||||
lottery_checker.state <== state;
|
||||
lottery_checker.note_nonce <== note_nonce;
|
||||
lottery_checker.nullifier_secret_key <== nullifier_secret_key;
|
||||
lottery_checker.randomness <== randomness;
|
||||
|
||||
|
||||
// Compute the note commitment
|
||||
component note_committer = commitment_computer();
|
||||
note_committer.note_nonce <== note_nonce;
|
||||
note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer.value <== value;
|
||||
|
||||
// Check the commitment membership
|
||||
component membership_checker = membership_checker();
|
||||
membership_checker.leaf <== note_committer.commitment;
|
||||
membership_checker.root <== commitments_root;
|
||||
for(var i =0; i<32; i++){
|
||||
membership_checker.index[i] <== index[i];
|
||||
membership_checker.node[i] <== nodes[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the note nullifier
|
||||
component nullifier_computer = nullifier_computer();
|
||||
nullifier_computer.note_nonce <== note_nonce;
|
||||
nullifier_computer.nullifier_secret_key <== nullifier_secret_key;
|
||||
nullifier_computer.value <== value;
|
||||
nullifier <== nullifier_computer.nullifier;
|
||||
|
||||
|
||||
// Compute the evolved nonce
|
||||
component nonce_updater = nonce_updater();
|
||||
nonce_updater.note_nonce <== note_nonce;
|
||||
nonce_updater.nullifier_secret_key <== nullifier_secret_key;
|
||||
|
||||
|
||||
// Compute the new note commitment
|
||||
component updated_note_committer = commitment_computer();
|
||||
updated_note_committer.note_nonce <== nonce_updater.updated_nonce;
|
||||
updated_note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer.value <== value;
|
||||
updated_commiment <== updated_note_committer.commitment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [epoch_nonce, slot_number, t0, t1, commitments_root]} = poseidon_sha_proof_of_leadership();
|
||||
@ -1,683 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/circomlib/circuits/sha256/sha256.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template lottery_ticket() {
|
||||
signal input epoch_nonce[256]; //F_p (BLS12-381 scalar field)
|
||||
signal input slot_number[64]; //F_p (BLS12-381 scalar field)
|
||||
signal input note_nonce[256];
|
||||
signal input nullifier_secret_key[256];
|
||||
|
||||
signal output r; //The lottery ticket in F_p
|
||||
|
||||
component hash = Sha256(864);
|
||||
|
||||
//The b"lead" Tag in bits with big endian order
|
||||
hash.in[0] <== 0;
|
||||
hash.in[1] <== 1;
|
||||
hash.in[2] <== 1;
|
||||
hash.in[3] <== 0;
|
||||
hash.in[4] <== 1;
|
||||
hash.in[5] <== 1;
|
||||
hash.in[6] <== 0;
|
||||
hash.in[7] <== 0;
|
||||
hash.in[8] <== 0;
|
||||
hash.in[9] <== 1;
|
||||
hash.in[10] <== 1;
|
||||
hash.in[11] <== 0;
|
||||
hash.in[12] <== 0;
|
||||
hash.in[13] <== 1;
|
||||
hash.in[14] <== 0;
|
||||
hash.in[15] <== 1;
|
||||
hash.in[16] <== 0;
|
||||
hash.in[17] <== 1;
|
||||
hash.in[18] <== 1;
|
||||
hash.in[19] <== 0;
|
||||
hash.in[20] <== 0;
|
||||
hash.in[21] <== 0;
|
||||
hash.in[22] <== 0;
|
||||
hash.in[23] <== 1;
|
||||
hash.in[24] <== 0;
|
||||
hash.in[25] <== 1;
|
||||
hash.in[26] <== 1;
|
||||
hash.in[27] <== 0;
|
||||
hash.in[28] <== 0;
|
||||
hash.in[29] <== 1;
|
||||
hash.in[30] <== 0;
|
||||
hash.in[31] <== 0;
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
hash.in[32+i] <== epoch_nonce[i];
|
||||
if(i<64){
|
||||
hash.in[288+i] <== slot_number[i];
|
||||
}
|
||||
hash.in[352+i] <== nullifier_secret_key[i];
|
||||
hash.in[608+i] <== note_nonce[i];
|
||||
}
|
||||
|
||||
component intifier = Bits2Num(253); //Because if the scalar field is 255 bits, we support every number of 254 bits (not all of 255) and we can only compare numbers of 253 bits since we need 1 bit for sign.
|
||||
|
||||
for(var i=0; i<253; i++){
|
||||
intifier.in[i] <== hash.out[253-i];
|
||||
}
|
||||
|
||||
r <== intifier.out;
|
||||
}
|
||||
|
||||
template check_lottery(){
|
||||
signal input pre_computed_threshold; //253 bits
|
||||
signal input v; //253 bits max
|
||||
signal input epoch_nonce[256];
|
||||
signal input slot_number[64];
|
||||
signal input nullifier_secret_key[256];
|
||||
signal input note_nonce[256];
|
||||
|
||||
component ticket = lottery_ticket();
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
ticket.epoch_nonce[i] <== epoch_nonce[i];
|
||||
if(i<64){
|
||||
ticket.slot_number[i] <== slot_number[i];
|
||||
}
|
||||
ticket.nullifier_secret_key[i] <== nullifier_secret_key[i];
|
||||
ticket.note_nonce[i] <== note_nonce[i];
|
||||
}
|
||||
|
||||
component isLess = BLSLessThan(253);
|
||||
|
||||
isLess.in[0] <== ticket.r;
|
||||
isLess.in[1] <== pre_computed_threshold * v;
|
||||
//isLess.out === 1;
|
||||
}
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce[256];
|
||||
signal input nullifier_public_key[256];
|
||||
signal input v[256];
|
||||
signal output nullifier[256];
|
||||
|
||||
component hash = Sha256(880);
|
||||
|
||||
//The b"coin-nullifier" Tag in bits with big endian order
|
||||
hash.in[0] <== 0;
|
||||
hash.in[1] <== 1;
|
||||
hash.in[2] <== 1;
|
||||
hash.in[3] <== 0;
|
||||
hash.in[4] <== 0;
|
||||
hash.in[5] <== 0;
|
||||
hash.in[6] <== 1;
|
||||
hash.in[7] <== 1;
|
||||
hash.in[8] <== 0;
|
||||
hash.in[9] <== 1;
|
||||
hash.in[10] <== 1;
|
||||
hash.in[11] <== 0;
|
||||
hash.in[12] <== 1;
|
||||
hash.in[13] <== 1;
|
||||
hash.in[14] <== 1;
|
||||
hash.in[15] <== 1;
|
||||
hash.in[16] <== 0;
|
||||
hash.in[17] <== 1;
|
||||
hash.in[18] <== 1;
|
||||
hash.in[19] <== 0;
|
||||
hash.in[20] <== 1;
|
||||
hash.in[21] <== 0;
|
||||
hash.in[22] <== 0;
|
||||
hash.in[23] <== 1;
|
||||
hash.in[24] <== 0;
|
||||
hash.in[25] <== 1;
|
||||
hash.in[26] <== 1;
|
||||
hash.in[27] <== 0;
|
||||
hash.in[28] <== 1;
|
||||
hash.in[29] <== 1;
|
||||
hash.in[30] <== 1;
|
||||
hash.in[31] <== 0;
|
||||
hash.in[32] <== 0;
|
||||
hash.in[33] <== 0;
|
||||
hash.in[34] <== 1;
|
||||
hash.in[35] <== 0;
|
||||
hash.in[36] <== 1;
|
||||
hash.in[37] <== 1;
|
||||
hash.in[38] <== 0;
|
||||
hash.in[39] <== 1;
|
||||
hash.in[40] <== 0;
|
||||
hash.in[41] <== 1;
|
||||
hash.in[42] <== 1;
|
||||
hash.in[43] <== 0;
|
||||
hash.in[44] <== 1;
|
||||
hash.in[45] <== 1;
|
||||
hash.in[46] <== 1;
|
||||
hash.in[47] <== 0;
|
||||
hash.in[48] <== 0;
|
||||
hash.in[49] <== 1;
|
||||
hash.in[50] <== 1;
|
||||
hash.in[51] <== 1;
|
||||
hash.in[52] <== 0;
|
||||
hash.in[53] <== 1;
|
||||
hash.in[54] <== 0;
|
||||
hash.in[55] <== 1;
|
||||
hash.in[56] <== 0;
|
||||
hash.in[57] <== 1;
|
||||
hash.in[58] <== 1;
|
||||
hash.in[59] <== 0;
|
||||
hash.in[60] <== 1;
|
||||
hash.in[61] <== 1;
|
||||
hash.in[62] <== 0;
|
||||
hash.in[63] <== 0;
|
||||
hash.in[64] <== 0;
|
||||
hash.in[65] <== 1;
|
||||
hash.in[66] <== 1;
|
||||
hash.in[67] <== 0;
|
||||
hash.in[68] <== 1;
|
||||
hash.in[69] <== 1;
|
||||
hash.in[70] <== 0;
|
||||
hash.in[71] <== 0;
|
||||
hash.in[72] <== 0;
|
||||
hash.in[73] <== 1;
|
||||
hash.in[74] <== 1;
|
||||
hash.in[75] <== 0;
|
||||
hash.in[76] <== 1;
|
||||
hash.in[77] <== 0;
|
||||
hash.in[78] <== 0;
|
||||
hash.in[79] <== 1;
|
||||
hash.in[80] <== 0;
|
||||
hash.in[81] <== 1;
|
||||
hash.in[82] <== 1;
|
||||
hash.in[83] <== 0;
|
||||
hash.in[84] <== 0;
|
||||
hash.in[85] <== 1;
|
||||
hash.in[86] <== 1;
|
||||
hash.in[87] <== 0;
|
||||
hash.in[88] <== 0;
|
||||
hash.in[89] <== 1;
|
||||
hash.in[90] <== 1;
|
||||
hash.in[91] <== 0;
|
||||
hash.in[92] <== 1;
|
||||
hash.in[93] <== 0;
|
||||
hash.in[94] <== 0;
|
||||
hash.in[95] <== 1;
|
||||
hash.in[96] <== 0;
|
||||
hash.in[97] <== 1;
|
||||
hash.in[98] <== 1;
|
||||
hash.in[99] <== 0;
|
||||
hash.in[100] <== 0;
|
||||
hash.in[101] <== 1;
|
||||
hash.in[102] <== 0;
|
||||
hash.in[103] <== 1;
|
||||
hash.in[104] <== 0;
|
||||
hash.in[105] <== 1;
|
||||
hash.in[106] <== 1;
|
||||
hash.in[107] <== 1;
|
||||
hash.in[108] <== 0;
|
||||
hash.in[109] <== 0;
|
||||
hash.in[110] <== 1;
|
||||
hash.in[111] <== 0;
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
hash.in[112+i] <== note_nonce[i];
|
||||
hash.in[368+i] <== nullifier_public_key[i];
|
||||
hash.in[624+i] <== v[i];
|
||||
}
|
||||
for(var i=0; i<256; i++){
|
||||
nullifier[i] <== hash.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template commitment_computer(){ // TODO: ensure all field are hash
|
||||
signal input note_nonce[256];
|
||||
signal input nullifier_public_key[256];
|
||||
signal input v[256];
|
||||
signal output commitment[256];
|
||||
|
||||
component hash = Sha256(888);
|
||||
|
||||
//The b"coin-commitment" Tag in bits with big endian order
|
||||
hash.in[0] <== 0;
|
||||
hash.in[1] <== 1;
|
||||
hash.in[2] <== 1;
|
||||
hash.in[3] <== 0;
|
||||
hash.in[4] <== 0;
|
||||
hash.in[5] <== 0;
|
||||
hash.in[6] <== 1;
|
||||
hash.in[7] <== 1;
|
||||
hash.in[8] <== 0;
|
||||
hash.in[9] <== 1;
|
||||
hash.in[10] <== 1;
|
||||
hash.in[11] <== 0;
|
||||
hash.in[12] <== 1;
|
||||
hash.in[13] <== 1;
|
||||
hash.in[14] <== 1;
|
||||
hash.in[15] <== 1;
|
||||
hash.in[16] <== 0;
|
||||
hash.in[17] <== 1;
|
||||
hash.in[18] <== 1;
|
||||
hash.in[19] <== 0;
|
||||
hash.in[20] <== 1;
|
||||
hash.in[21] <== 0;
|
||||
hash.in[22] <== 0;
|
||||
hash.in[23] <== 1;
|
||||
hash.in[24] <== 0;
|
||||
hash.in[25] <== 1;
|
||||
hash.in[26] <== 1;
|
||||
hash.in[27] <== 0;
|
||||
hash.in[28] <== 1;
|
||||
hash.in[29] <== 1;
|
||||
hash.in[30] <== 1;
|
||||
hash.in[31] <== 0;
|
||||
hash.in[32] <== 0;
|
||||
hash.in[33] <== 0;
|
||||
hash.in[34] <== 1;
|
||||
hash.in[35] <== 0;
|
||||
hash.in[36] <== 1;
|
||||
hash.in[37] <== 1;
|
||||
hash.in[38] <== 0;
|
||||
hash.in[39] <== 1;
|
||||
hash.in[40] <== 0;
|
||||
hash.in[41] <== 1;
|
||||
hash.in[42] <== 1;
|
||||
hash.in[43] <== 0;
|
||||
hash.in[44] <== 0;
|
||||
hash.in[45] <== 0;
|
||||
hash.in[46] <== 1;
|
||||
hash.in[47] <== 1;
|
||||
hash.in[48] <== 0;
|
||||
hash.in[49] <== 1;
|
||||
hash.in[50] <== 1;
|
||||
hash.in[51] <== 0;
|
||||
hash.in[52] <== 1;
|
||||
hash.in[53] <== 1;
|
||||
hash.in[54] <== 1;
|
||||
hash.in[55] <== 1;
|
||||
hash.in[56] <== 0;
|
||||
hash.in[57] <== 1;
|
||||
hash.in[58] <== 1;
|
||||
hash.in[59] <== 0;
|
||||
hash.in[60] <== 1;
|
||||
hash.in[61] <== 1;
|
||||
hash.in[62] <== 0;
|
||||
hash.in[63] <== 1;
|
||||
hash.in[64] <== 0;
|
||||
hash.in[65] <== 1;
|
||||
hash.in[66] <== 1;
|
||||
hash.in[67] <== 0;
|
||||
hash.in[68] <== 1;
|
||||
hash.in[69] <== 1;
|
||||
hash.in[70] <== 0;
|
||||
hash.in[71] <== 1;
|
||||
hash.in[72] <== 0;
|
||||
hash.in[73] <== 1;
|
||||
hash.in[74] <== 1;
|
||||
hash.in[75] <== 0;
|
||||
hash.in[76] <== 1;
|
||||
hash.in[77] <== 0;
|
||||
hash.in[78] <== 0;
|
||||
hash.in[79] <== 1;
|
||||
hash.in[80] <== 0;
|
||||
hash.in[81] <== 1;
|
||||
hash.in[82] <== 1;
|
||||
hash.in[83] <== 1;
|
||||
hash.in[84] <== 0;
|
||||
hash.in[85] <== 1;
|
||||
hash.in[86] <== 0;
|
||||
hash.in[87] <== 0;
|
||||
hash.in[88] <== 0;
|
||||
hash.in[89] <== 1;
|
||||
hash.in[90] <== 1;
|
||||
hash.in[91] <== 0;
|
||||
hash.in[92] <== 1;
|
||||
hash.in[93] <== 1;
|
||||
hash.in[94] <== 0;
|
||||
hash.in[95] <== 1;
|
||||
hash.in[96] <== 0;
|
||||
hash.in[97] <== 1;
|
||||
hash.in[98] <== 1;
|
||||
hash.in[99] <== 0;
|
||||
hash.in[100] <== 0;
|
||||
hash.in[101] <== 1;
|
||||
hash.in[102] <== 0;
|
||||
hash.in[103] <== 1;
|
||||
hash.in[104] <== 0;
|
||||
hash.in[105] <== 1;
|
||||
hash.in[106] <== 1;
|
||||
hash.in[107] <== 0;
|
||||
hash.in[108] <== 1;
|
||||
hash.in[109] <== 1;
|
||||
hash.in[110] <== 1;
|
||||
hash.in[111] <== 0;
|
||||
hash.in[112] <== 0;
|
||||
hash.in[113] <== 1;
|
||||
hash.in[114] <== 1;
|
||||
hash.in[115] <== 1;
|
||||
hash.in[116] <== 0;
|
||||
hash.in[117] <== 1;
|
||||
hash.in[118] <== 0;
|
||||
hash.in[119] <== 0;
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
hash.in[120+i] <== note_nonce[i];
|
||||
hash.in[376+i] <== nullifier_public_key[i];
|
||||
hash.in[632+i] <== v[i];
|
||||
}
|
||||
for(var i=0; i<256; i++){
|
||||
commitment[i] <== hash.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce[256];
|
||||
signal input nullifier_secret_key[256];
|
||||
signal output updated_nonce[256];
|
||||
|
||||
component hash = Sha256(600);
|
||||
|
||||
//The b"coin-evolve" Tag in bits with big endian order
|
||||
hash.in[0] <== 0;
|
||||
hash.in[1] <== 1;
|
||||
hash.in[2] <== 1;
|
||||
hash.in[3] <== 0;
|
||||
hash.in[4] <== 0;
|
||||
hash.in[5] <== 0;
|
||||
hash.in[6] <== 1;
|
||||
hash.in[7] <== 1;
|
||||
hash.in[8] <== 0;
|
||||
hash.in[9] <== 1;
|
||||
hash.in[10] <== 1;
|
||||
hash.in[11] <== 0;
|
||||
hash.in[12] <== 1;
|
||||
hash.in[13] <== 1;
|
||||
hash.in[14] <== 1;
|
||||
hash.in[15] <== 1;
|
||||
hash.in[16] <== 0;
|
||||
hash.in[17] <== 1;
|
||||
hash.in[18] <== 1;
|
||||
hash.in[19] <== 0;
|
||||
hash.in[20] <== 1;
|
||||
hash.in[21] <== 0;
|
||||
hash.in[22] <== 0;
|
||||
hash.in[23] <== 1;
|
||||
hash.in[24] <== 0;
|
||||
hash.in[25] <== 1;
|
||||
hash.in[26] <== 1;
|
||||
hash.in[27] <== 0;
|
||||
hash.in[28] <== 1;
|
||||
hash.in[29] <== 1;
|
||||
hash.in[30] <== 1;
|
||||
hash.in[31] <== 0;
|
||||
hash.in[32] <== 0;
|
||||
hash.in[33] <== 0;
|
||||
hash.in[34] <== 1;
|
||||
hash.in[35] <== 0;
|
||||
hash.in[36] <== 1;
|
||||
hash.in[37] <== 1;
|
||||
hash.in[38] <== 0;
|
||||
hash.in[39] <== 1;
|
||||
hash.in[40] <== 0;
|
||||
hash.in[41] <== 1;
|
||||
hash.in[42] <== 1;
|
||||
hash.in[43] <== 0;
|
||||
hash.in[44] <== 0;
|
||||
hash.in[45] <== 1;
|
||||
hash.in[46] <== 0;
|
||||
hash.in[47] <== 1;
|
||||
hash.in[48] <== 0;
|
||||
hash.in[49] <== 1;
|
||||
hash.in[50] <== 1;
|
||||
hash.in[51] <== 1;
|
||||
hash.in[52] <== 0;
|
||||
hash.in[53] <== 1;
|
||||
hash.in[54] <== 1;
|
||||
hash.in[55] <== 0;
|
||||
hash.in[56] <== 0;
|
||||
hash.in[57] <== 1;
|
||||
hash.in[58] <== 1;
|
||||
hash.in[59] <== 0;
|
||||
hash.in[60] <== 1;
|
||||
hash.in[61] <== 1;
|
||||
hash.in[62] <== 1;
|
||||
hash.in[63] <== 1;
|
||||
hash.in[64] <== 0;
|
||||
hash.in[65] <== 1;
|
||||
hash.in[66] <== 1;
|
||||
hash.in[67] <== 0;
|
||||
hash.in[68] <== 1;
|
||||
hash.in[69] <== 1;
|
||||
hash.in[70] <== 0;
|
||||
hash.in[71] <== 0;
|
||||
hash.in[72] <== 0;
|
||||
hash.in[73] <== 1;
|
||||
hash.in[74] <== 1;
|
||||
hash.in[75] <== 1;
|
||||
hash.in[76] <== 0;
|
||||
hash.in[77] <== 1;
|
||||
hash.in[78] <== 1;
|
||||
hash.in[79] <== 0;
|
||||
hash.in[80] <== 0;
|
||||
hash.in[81] <== 1;
|
||||
hash.in[82] <== 1;
|
||||
hash.in[83] <== 0;
|
||||
hash.in[84] <== 0;
|
||||
hash.in[85] <== 1;
|
||||
hash.in[86] <== 0;
|
||||
hash.in[87] <== 1;
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
hash.in[88+i] <== note_nonce[i];
|
||||
hash.in[344+i] <== nullifier_secret_key[i];
|
||||
}
|
||||
for(var i=0; i<256; i++){
|
||||
updated_nonce[i] <== hash.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template sha_2_to_1(){
|
||||
signal input a[256];
|
||||
signal input b[256];
|
||||
signal output hash_ab[256];
|
||||
|
||||
component hash = Sha256(512);
|
||||
for(var i=0; i<256; i++){
|
||||
hash.in[i] <== a[i];
|
||||
hash.in[i+256] <== b[i];
|
||||
}
|
||||
|
||||
for(var i=0;i<256;i++){
|
||||
hash_ab[i] <== hash.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input commitment[256]; //The note commitment
|
||||
signal input commitments_root[256]; //The root of the Merkle Tree containing every commitments (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32][256]; //Complementary hashes
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = sha_2_to_1();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
hash[0].a[i] <== commitment[i] - index[31] * (commitment[i] - node[0][i]);
|
||||
hash[0].b[i] <== node[0][i] - index[31] * (node[0][i] - commitment[i]);
|
||||
}
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
for(var j=0; j<256; j++){
|
||||
hash[i].a[j] <== hash[i-1].hash_ab[j] - index[31] * (hash[i-1].hash_ab[j] - node[i][j]);
|
||||
hash[i].b[j] <== node[i][j] - index[31] * (node[i][j] - hash[i-1].hash_ab[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for(var i=0; i<256; i++){
|
||||
//commitments_root[i] === hash[31].hash_ab[i];
|
||||
}
|
||||
}
|
||||
|
||||
template bits2num_253(){
|
||||
signal input bits[253];
|
||||
signal output value;
|
||||
|
||||
signal intermediate_value[252];
|
||||
intermediate_value[0] <== bits[0] * 2;
|
||||
for(var i=1; i<252; i++){
|
||||
intermediate_value[i] <== intermediate_value[i-1] * 2 + bits[i];
|
||||
}
|
||||
value <== intermediate_value[251] * 2 + bits[252];
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template sha_proof_of_leadership(){
|
||||
signal input epoch_nonce[256]; //256 bits
|
||||
signal input slot_number[64]; //64 bits
|
||||
signal input pre_computed_threshold; //253 bits
|
||||
signal input commitments_root[256]; //The root of the Merkle Tree containing every commitments (of depth 32) 256 bits
|
||||
|
||||
signal input note_nonce[256];
|
||||
signal input nullifier_secret_key[256];
|
||||
signal input v[253]; //253 bits
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32][256]; //Complementary hashes
|
||||
|
||||
signal output nullifier[256];
|
||||
signal output updated_commiment[256];
|
||||
|
||||
|
||||
// Check that private inputs are indeed bits
|
||||
component bit_checker[36];
|
||||
for(var i=0; i<34; i++){
|
||||
bit_checker[i] = check_bits(256);
|
||||
if(i<32){
|
||||
for(var j=0; j<256; j++){
|
||||
bit_checker[i].bits[j] <== node[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
bit_checker[34] = check_bits(253);
|
||||
bit_checker[35] = check_bits(32);
|
||||
for(var i=0; i<256; i++){
|
||||
bit_checker[32].bits[i] <== note_nonce[i];
|
||||
bit_checker[33].bits[i] <== nullifier_secret_key[i];
|
||||
if(i<253){
|
||||
bit_checker[34].bits[i] <== v[i];
|
||||
}
|
||||
if(i<32){
|
||||
bit_checker[35].bits[i] <== index[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the value of v
|
||||
component bits2num = bits2num_253();
|
||||
for(var i=0; i<253; i++){
|
||||
bits2num.bits[i] <== v[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Check that r < threshold
|
||||
component lottery_checker = check_lottery();
|
||||
lottery_checker.pre_computed_threshold <== pre_computed_threshold;
|
||||
lottery_checker.v <== bits2num.value;
|
||||
for(var i=0; i<256; i++){
|
||||
lottery_checker.epoch_nonce[i] <== epoch_nonce[i];
|
||||
if(i<64){
|
||||
lottery_checker.slot_number[i] <== slot_number[i];
|
||||
}
|
||||
lottery_checker.nullifier_secret_key[i] <== nullifier_secret_key[i];
|
||||
lottery_checker.note_nonce[i] <== note_nonce[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the note commitment
|
||||
component note_committer = commitment_computer();
|
||||
for(var i=0; i<256; i++){
|
||||
note_committer.note_nonce[i] <== note_nonce[i];
|
||||
note_committer.nullifier_public_key[i] <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
}
|
||||
note_committer.v[0] <== 0;
|
||||
note_committer.v[1] <== 0;
|
||||
note_committer.v[2] <== 0;
|
||||
for(var i=0; i<253; i++){
|
||||
note_committer.v[i+3] <== v[i];
|
||||
}
|
||||
|
||||
// Check the commitment membership
|
||||
component membership_checker = membership_checker();
|
||||
for(var i=0; i<256; i++){
|
||||
membership_checker.commitment[i] <== note_committer.commitment[i];
|
||||
membership_checker.commitments_root[i] <== commitments_root[i];
|
||||
for(var j=0; j<32; j++){
|
||||
if(i==0){
|
||||
membership_checker.index[j] <== index[j];
|
||||
}
|
||||
membership_checker.node[j][i] <== node[j][i];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the note nullifier
|
||||
component nullifier_computer = nullifier_computer();
|
||||
for(var i=0; i<256; i++){
|
||||
nullifier_computer.note_nonce[i] <== note_nonce[i];
|
||||
nullifier_computer.nullifier_public_key[i] <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
}
|
||||
nullifier_computer.v[0] <== 0;
|
||||
nullifier_computer.v[1] <== 0;
|
||||
nullifier_computer.v[2] <== 0;
|
||||
for(var i=0; i<253; i++){
|
||||
nullifier_computer.v[i+3] <== v[i];
|
||||
}
|
||||
for(var i=0; i<256; i++){
|
||||
nullifier[i] <== nullifier_computer.nullifier[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the evolved nonce
|
||||
component nonce_updater = nonce_updater();
|
||||
for(var i=0; i<256; i++){
|
||||
nonce_updater.note_nonce[i] <== note_nonce[i];
|
||||
nonce_updater.nullifier_secret_key[i] <== nullifier_secret_key[i];
|
||||
}
|
||||
|
||||
// Compute the new note commitment
|
||||
component updated_note_committer = commitment_computer();
|
||||
for(var i=0; i<256; i++){
|
||||
updated_note_committer.note_nonce[i] <== nonce_updater.updated_nonce[i];
|
||||
updated_note_committer.nullifier_public_key[i] <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
}
|
||||
updated_note_committer.v[0] <== 0;
|
||||
updated_note_committer.v[1] <== 0;
|
||||
updated_note_committer.v[2] <== 0;
|
||||
for(var i=0; i<253; i++){
|
||||
updated_note_committer.v[i+3] <== v[i];
|
||||
}
|
||||
for(var i =0; i<256; i++){
|
||||
updated_commiment[i] <== updated_note_committer.commitment[i];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [epoch_nonce, slot_number, pre_computed_threshold, commitments_root]} = sha_proof_of_leadership();
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"cells": [],
|
||||
"metadata": {},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,209 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/comparators.circom";
|
||||
include "../../circom_circuits/Jubjub/escalarmulanyJubjub.circom";
|
||||
include "../../circom_circuits/Jubjub/jubjub.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template BLSNum2Bits_strict() {
|
||||
signal input in;
|
||||
signal output out[255];
|
||||
|
||||
component check_range = CompConstant(23487852865797141623554994256013988874373056334117496812739262697960298774528); // -1 - 2**254 (p-1 without its first bit)
|
||||
component n2b = Num2Bits(255);
|
||||
in ==> n2b.in;
|
||||
|
||||
for (var i=0; i<255; i++) {
|
||||
n2b.out[i] ==> out[i];
|
||||
if(i != 0){
|
||||
n2b.out[i] ==> check_range.in[i-1];
|
||||
}
|
||||
}
|
||||
|
||||
check_range.out * (n2b.out[0]) === 0; //must be zero exept if the first bit is 0 => then in is on 254 bits and p-1 on 255
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template commitment_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal input constraints;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_16_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
hash.in[4] <== constraints;
|
||||
hash.in[5] <== unit;
|
||||
hash.in[6] <== state;
|
||||
for(var i=7; i<16; i++){
|
||||
hash.in[i] <== 0;
|
||||
}
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input note_commitment;
|
||||
signal input pedersen_randomness;
|
||||
signal input pedersen_commitment[2];
|
||||
signal input h_curve_point[2];
|
||||
|
||||
component note_commitment_bitifier = Num2Bits(255);
|
||||
component pedersen_randomness_bitifier = BLSNum2Bits_strict();
|
||||
note_commitment_bitifier.in <== note_commitment;
|
||||
pedersen_randomness_bitifier.in <== pedersen_randomness;
|
||||
|
||||
// A is note_cm * G and B is r * H
|
||||
component A = EscalarMulAny(255);
|
||||
component B = EscalarMulAny(255);
|
||||
|
||||
A.p[0] <== 0x11dafe5d23e1218086a365b99fbf3d3be72f6afd7d1f72623e6b071492d1122b;
|
||||
A.p[1] <== 0x1d523cf1ddab1a1793132e78c866c0c33e26ba5cc220fed7cc3f870e59d292aa;
|
||||
B.p[0] <== h_curve_point[0];
|
||||
B.p[1] <== h_curve_point[1];
|
||||
for(var i =0; i<255; i++){
|
||||
A.e[i] <== note_commitment_bitifier.out[i];
|
||||
B.e[i] <== pedersen_randomness_bitifier.out[i];
|
||||
}
|
||||
|
||||
component pedersen = JubjubAdd();
|
||||
pedersen.x1 <== A.out[0];
|
||||
pedersen.y1 <== A.out[1];
|
||||
pedersen.x2 <== B.out[0];
|
||||
pedersen.y2 <== B.out[1];
|
||||
|
||||
pedersen.xout === pedersen_commitment[0];
|
||||
pedersen.yout === pedersen_commitment[1];
|
||||
|
||||
}
|
||||
|
||||
template caulk_proof_of_validator(minimum_stake){ //TODO: put minimum_stake in the input to change it dynamically
|
||||
signal input pedersen_commitment[2];
|
||||
signal input h_curve_point[2];
|
||||
|
||||
// Note variables
|
||||
signal input constraints; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value; // 0 if no more notes needed
|
||||
signal input unit;
|
||||
signal input state; // This field hold the identity of the owner (its public key or ID) and is revealed
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
|
||||
signal input pedersen_randomness;
|
||||
|
||||
signal output nullifiers;
|
||||
signal output updated_commiments;
|
||||
|
||||
// Compute the note commitments
|
||||
component note_committer = commitment_computer();
|
||||
note_committer.note_nonce <== note_nonce;
|
||||
note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer.value <== value;
|
||||
note_committer.constraints <== constraints;
|
||||
note_committer.unit <== unit;
|
||||
note_committer.state <== state;
|
||||
|
||||
// Check the commitments membership
|
||||
component membership_checker = membership_checker();
|
||||
membership_checker.note_commitment <== note_committer.commitment;
|
||||
membership_checker.pedersen_randomness <== pedersen_randomness;
|
||||
membership_checker.pedersen_commitment[0] <== pedersen_commitment[0];
|
||||
membership_checker.pedersen_commitment[1] <== pedersen_commitment[1];
|
||||
membership_checker.h_curve_point[0] <== h_curve_point[0];
|
||||
membership_checker.h_curve_point[1] <== h_curve_point[1];
|
||||
|
||||
// Check that the value exceed the minimum stake
|
||||
component isLess = BLSLessThan(253);
|
||||
isLess.in[0] <== minimum_stake;
|
||||
isLess.in[1] <== value;
|
||||
isLess.out === 1;
|
||||
|
||||
// Compute the note nullifiers
|
||||
component nullifier_computer = nullifier_computer();
|
||||
nullifier_computer.note_nonce <== note_nonce;
|
||||
nullifier_computer.nullifier_secret_key <== nullifier_secret_key;
|
||||
nullifier_computer.value <== value;
|
||||
nullifiers <== nullifier_computer.nullifier;
|
||||
|
||||
// Compute the evolved nonces
|
||||
component nonce_updater = nonce_updater();
|
||||
nonce_updater.note_nonce <== note_nonce;
|
||||
nonce_updater.nullifier_secret_key <== nullifier_secret_key;
|
||||
|
||||
// Compute the new note commitments
|
||||
component updated_note_committer = commitment_computer();
|
||||
updated_note_committer.note_nonce <== nonce_updater.updated_nonce;
|
||||
updated_note_committer.nullifier_public_key <== nullifier_secret_key; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer.value <== value;
|
||||
updated_note_committer.constraints <== constraints;
|
||||
updated_note_committer.unit <== unit;
|
||||
updated_note_committer.state <== state;
|
||||
updated_commiments <== updated_note_committer.commitment;
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [state,pedersen_commitment,h_curve_point]} = caulk_proof_of_validator(10000);
|
||||
@ -1,226 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/anemoi/anemoi_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/comparators.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template commitment_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal input constraints;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_16_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
hash.in[4] <== constraints;
|
||||
hash.in[5] <== unit;
|
||||
hash.in[6] <== state;
|
||||
for(var i=7; i<16; i++){
|
||||
hash.in[i] <== 0;
|
||||
}
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input leaf; //The note commitment
|
||||
signal input root; //The root of the Merkle Tree (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32]; //Complementary hashes
|
||||
signal input is_null; //If is_null is 1 we don't check the membership (any value of node and index will be correct)
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = hash_2_to_1();
|
||||
}
|
||||
|
||||
hash[0].in[0] <== leaf - index[31] * (leaf - node[0]);
|
||||
hash[0].in[1] <== node[0] - index[31] * (node[0] - leaf);
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
hash[i].in[0] <== hash[i-1].out - index[31-i] * (hash[i-1].out - node[i]);
|
||||
hash[i].in[1] <== node[i] - index[31-i] * (node[i] - hash[i-1].out);
|
||||
}
|
||||
|
||||
root === hash[31].out * (1 - is_null);
|
||||
|
||||
}
|
||||
|
||||
template anemoi_proof_of_validator(max_notes){
|
||||
signal input commitments_root;
|
||||
signal input minimum_stake;
|
||||
|
||||
// Note variables
|
||||
signal input constraints[max_notes]; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value[max_notes]; // 0 if no more notes needed
|
||||
signal input unit[max_notes];
|
||||
signal input state[max_notes]; // This field hold the identity of the owner (its public key or ID)
|
||||
signal input note_nonce[max_notes];
|
||||
signal input nullifier_secret_key[max_notes];
|
||||
signal input index[max_notes][32]; //Position of the note commitment in bits in big endian
|
||||
signal input nodes[max_notes][32]; //Merkle proof of the commitment
|
||||
|
||||
signal output identity;
|
||||
signal output nullifiers[max_notes];
|
||||
signal output updated_commiments[max_notes];
|
||||
|
||||
|
||||
// Check that index inputs are indeed bits
|
||||
component bit_checker[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
bit_checker[i] = check_bits(32);
|
||||
for(var j=0; j<32; j++){
|
||||
bit_checker[i].bits[j] <== index[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the note commitments
|
||||
component note_committer[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
note_committer[i] = commitment_computer();
|
||||
note_committer[i].note_nonce <== note_nonce[i];
|
||||
note_committer[i].nullifier_public_key <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer[i].value <== value[i];
|
||||
note_committer[i].constraints <== constraints[i];
|
||||
note_committer[i].unit <== unit[i];
|
||||
note_committer[i].state <== state[i];
|
||||
}
|
||||
|
||||
//check the identity between the notes
|
||||
identity <== state[0]; // The first note must not be null
|
||||
component is_null[max_notes];
|
||||
is_null[0] = IsZero();
|
||||
is_null[0].in <== value[0];
|
||||
is_null[0].out === 0;
|
||||
signal intermediate[max_notes-1];
|
||||
for(var i=1; i<max_notes; i++){
|
||||
is_null[i] = IsZero();
|
||||
is_null[i].in <== value[i];
|
||||
intermediate[i-1] <== identity * (1 - is_null[i].out);
|
||||
intermediate[i-1] === state[i] * (1 - is_null[i].out);
|
||||
}
|
||||
|
||||
// Check the commitments membership
|
||||
component membership_checker[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
membership_checker[i] = membership_checker();
|
||||
membership_checker[i].leaf <== note_committer[i].commitment;
|
||||
membership_checker[i].root <== commitments_root * (1- is_null[i].out); // Set the root at 0 is note is null
|
||||
membership_checker[i].is_null <== is_null[i].out;
|
||||
for(var j =0; j<32; j++){
|
||||
membership_checker[i].index[j] <== index[i][j];
|
||||
membership_checker[i].node[j] <== nodes[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the value exceed the minimum stake
|
||||
signal sum[max_notes-1];
|
||||
sum[0] <== value[0] + value[1];
|
||||
for(var i = 1; i<max_notes-1; i++){
|
||||
sum[i] <== sum[i-1] + value[i+1];
|
||||
}
|
||||
component isLess = BLSLessThan(253);
|
||||
isLess.in[0] <== minimum_stake;
|
||||
isLess.in[1] <== sum[max_notes-2];
|
||||
isLess.out === 1;
|
||||
|
||||
|
||||
// Compute the note nullifiers
|
||||
component nullifier_computer[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
nullifier_computer[i] = nullifier_computer();
|
||||
nullifier_computer[i].note_nonce <== note_nonce[i];
|
||||
nullifier_computer[i].nullifier_secret_key <== nullifier_secret_key[i];
|
||||
nullifier_computer[i].value <== value[i];
|
||||
nullifiers[i] <== nullifier_computer[i].nullifier;
|
||||
}
|
||||
|
||||
// Compute the evolved nonces
|
||||
component nonce_updater[max_notes];
|
||||
for(var i=0; i<max_notes; i++) {
|
||||
nonce_updater[i] = nonce_updater();
|
||||
nonce_updater[i].note_nonce <== note_nonce[i];
|
||||
nonce_updater[i].nullifier_secret_key <== nullifier_secret_key[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the new note commitments
|
||||
component updated_note_committer[max_notes];
|
||||
for(var i=0; i<max_notes; i++) {
|
||||
updated_note_committer[i] = commitment_computer();
|
||||
updated_note_committer[i].note_nonce <== nonce_updater[i].updated_nonce;
|
||||
updated_note_committer[i].nullifier_public_key <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer[i].value <== value[i];
|
||||
updated_note_committer[i].constraints <== constraints[i];
|
||||
updated_note_committer[i].unit <== unit[i];
|
||||
updated_note_committer[i].state <== state[i];
|
||||
updated_commiments[i] <== updated_note_committer[i].commitment;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
component main {public [commitments_root, minimum_stake]} = anemoi_proof_of_validator(50);
|
||||
@ -1,227 +0,0 @@
|
||||
//test
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_2_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_4_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/hash/poseidon/poseidon_16_to_1_Jubjub.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/bitify.circom";
|
||||
include "../../circom_circuits/circomlib/circuits/comparators.circom";
|
||||
|
||||
template BLSLessThan(n) {
|
||||
assert(n <= 253);
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
template check_bits(n){
|
||||
signal input bits[n];
|
||||
for(var i=0; i<n; i++){
|
||||
bits[i] * (1-bits[i]) === 0;
|
||||
}
|
||||
}
|
||||
|
||||
template commitment_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_public_key;
|
||||
signal input value;
|
||||
signal input constraints;
|
||||
signal input unit;
|
||||
signal input state;
|
||||
signal output commitment;
|
||||
|
||||
component hash = hash_16_to_1();
|
||||
|
||||
//The b"coin-commitment" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 516297089516239580383111224192495220;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_public_key;
|
||||
hash.in[3] <== value;
|
||||
hash.in[4] <== constraints;
|
||||
hash.in[5] <== unit;
|
||||
hash.in[6] <== state;
|
||||
for(var i=7; i<16; i++){
|
||||
hash.in[i] <== 0;
|
||||
}
|
||||
|
||||
commitment <== hash.out;
|
||||
}
|
||||
|
||||
template nullifier_computer(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal input value;
|
||||
signal output nullifier;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-nullifier" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 2016785505923014207119328528655730;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== value;
|
||||
|
||||
nullifier <== hash.out;
|
||||
}
|
||||
|
||||
template nonce_updater(){
|
||||
signal input note_nonce;
|
||||
signal input nullifier_secret_key;
|
||||
signal output updated_nonce;
|
||||
|
||||
component hash = hash_4_to_1();
|
||||
|
||||
//The b"coin-evolve" Tag converted in F_p element (from bits with big endian order)
|
||||
hash.in[0] <== 120209783668687835891529317;
|
||||
hash.in[1] <== note_nonce;
|
||||
hash.in[2] <== nullifier_secret_key;
|
||||
hash.in[3] <== 0;
|
||||
|
||||
updated_nonce <== hash.out;
|
||||
}
|
||||
|
||||
template membership_checker(){
|
||||
signal input leaf; //The note commitment
|
||||
signal input root; //The root of the Merkle Tree (of depth 32)
|
||||
signal input index[32]; //Position of the note commitment in bits in big endian
|
||||
signal input node[32]; //Complementary hashes
|
||||
signal input is_null; //If is_null is 1 we don't check the membership (any value of node and index will be correct)
|
||||
|
||||
component hash[32];
|
||||
|
||||
for(var i=0; i<32; i++){
|
||||
hash[i] = hash_2_to_1();
|
||||
}
|
||||
|
||||
hash[0].in[0] <== leaf - index[31] * (leaf - node[0]);
|
||||
hash[0].in[1] <== node[0] - index[31] * (node[0] - leaf);
|
||||
|
||||
for(var i=1; i<32; i++){
|
||||
hash[i].in[0] <== hash[i-1].out - index[31-i] * (hash[i-1].out - node[i]);
|
||||
hash[i].in[1] <== node[i] - index[31-i] * (node[i] - hash[i-1].out);
|
||||
}
|
||||
|
||||
root === hash[31].out * (1 - is_null);
|
||||
|
||||
}
|
||||
|
||||
template poseidon_proof_of_validator(max_notes){
|
||||
signal input commitments_root;
|
||||
signal input minimum_stake;
|
||||
|
||||
// Note variables
|
||||
signal input constraints[max_notes]; // Every note field represented as F_p elements for now (constraints are represented by their Merkle root)
|
||||
signal input value[max_notes]; // 0 if no more notes needed
|
||||
signal input unit[max_notes];
|
||||
signal input state[max_notes]; // This field hold the identity of the owner (its public key or ID)
|
||||
signal input note_nonce[max_notes];
|
||||
signal input nullifier_secret_key[max_notes];
|
||||
signal input index[max_notes][32]; //Position of the note commitment in bits in big endian
|
||||
signal input nodes[max_notes][32]; //Merkle proof of the commitment
|
||||
|
||||
signal output identity;
|
||||
signal output nullifiers[max_notes];
|
||||
signal output updated_commiments[max_notes];
|
||||
|
||||
|
||||
// Check that index inputs are indeed bits
|
||||
component bit_checker[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
bit_checker[i] = check_bits(32);
|
||||
for(var j=0; j<32; j++){
|
||||
bit_checker[i].bits[j] <== index[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the note commitments
|
||||
component note_committer[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
note_committer[i] = commitment_computer();
|
||||
note_committer[i].note_nonce <== note_nonce[i];
|
||||
note_committer[i].nullifier_public_key <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
note_committer[i].value <== value[i];
|
||||
note_committer[i].constraints <== constraints[i];
|
||||
note_committer[i].unit <== unit[i];
|
||||
note_committer[i].state <== state[i];
|
||||
}
|
||||
|
||||
//check the identity between the notes
|
||||
identity <== state[0]; // The first note must not be null
|
||||
component is_null[max_notes];
|
||||
is_null[0] = IsZero();
|
||||
is_null[0].in <== value[0];
|
||||
is_null[0].out === 0;
|
||||
signal intermediate[max_notes-1];
|
||||
for(var i=1; i<max_notes; i++){
|
||||
is_null[i] = IsZero();
|
||||
is_null[i].in <== value[i];
|
||||
intermediate[i-1] <== identity * (1 - is_null[i].out);
|
||||
intermediate[i-1] === state[i] * (1 - is_null[i].out);
|
||||
}
|
||||
|
||||
// Check the commitments membership
|
||||
component membership_checker[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
membership_checker[i] = membership_checker();
|
||||
membership_checker[i].leaf <== note_committer[i].commitment;
|
||||
membership_checker[i].root <== commitments_root * (1- is_null[i].out); // Set the root at 0 is note is null
|
||||
membership_checker[i].is_null <== is_null[i].out;
|
||||
for(var j =0; j<32; j++){
|
||||
membership_checker[i].index[j] <== index[i][j];
|
||||
membership_checker[i].node[j] <== nodes[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the value exceed the minimum stake
|
||||
signal sum[max_notes-1];
|
||||
sum[0] <== value[0] + value[1];
|
||||
for(var i = 1; i<max_notes-1; i++){
|
||||
sum[i] <== sum[i-1] + value[i+1];
|
||||
}
|
||||
component isLess = BLSLessThan(253);
|
||||
isLess.in[0] <== minimum_stake;
|
||||
isLess.in[1] <== sum[max_notes-2];
|
||||
isLess.out === 1;
|
||||
|
||||
|
||||
// Compute the note nullifiers
|
||||
component nullifier_computer[max_notes];
|
||||
for(var i=0; i<max_notes; i++){
|
||||
nullifier_computer[i] = nullifier_computer();
|
||||
nullifier_computer[i].note_nonce <== note_nonce[i];
|
||||
nullifier_computer[i].nullifier_secret_key <== nullifier_secret_key[i];
|
||||
nullifier_computer[i].value <== value[i];
|
||||
nullifiers[i] <== nullifier_computer[i].nullifier;
|
||||
}
|
||||
|
||||
// Compute the evolved nonces
|
||||
component nonce_updater[max_notes];
|
||||
for(var i=0; i<max_notes; i++) {
|
||||
nonce_updater[i] = nonce_updater();
|
||||
nonce_updater[i].note_nonce <== note_nonce[i];
|
||||
nonce_updater[i].nullifier_secret_key <== nullifier_secret_key[i];
|
||||
}
|
||||
|
||||
|
||||
// Compute the new note commitments
|
||||
component updated_note_committer[max_notes];
|
||||
for(var i=0; i<max_notes; i++) {
|
||||
updated_note_committer[i] = commitment_computer();
|
||||
updated_note_committer[i].note_nonce <== nonce_updater[i].updated_nonce;
|
||||
updated_note_committer[i].nullifier_public_key <== nullifier_secret_key[i]; // TODO: reflect the nullifier public key computation later when defined
|
||||
updated_note_committer[i].value <== value[i];
|
||||
updated_note_committer[i].constraints <== constraints[i];
|
||||
updated_note_committer[i].unit <== unit[i];
|
||||
updated_note_committer[i].state <== state[i];
|
||||
updated_commiments[i] <== updated_note_committer[i].commitment;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
component main {public [commitments_root, minimum_stake]} = poseidon_proof_of_validator(50);
|
||||
Loading…
x
Reference in New Issue
Block a user