mirror of
https://github.com/selfxyz/self.git
synced 2026-01-10 15:18:18 -05:00
merge dev
This commit is contained in:
4
.github/workflows/action.yml
vendored
4
.github/workflows/action.yml
vendored
@@ -4,6 +4,7 @@ on:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
- openpassportv2
|
||||
paths:
|
||||
- 'circuits/**'
|
||||
- 'common/**'
|
||||
@@ -11,6 +12,7 @@ on:
|
||||
branches:
|
||||
- dev
|
||||
- main
|
||||
- openpassportv2
|
||||
paths:
|
||||
- 'circuits/**'
|
||||
- 'common/**'
|
||||
@@ -59,6 +61,8 @@ jobs:
|
||||
|
||||
- name: Run Tests (Circuits)
|
||||
working-directory: ./circuits
|
||||
env:
|
||||
FULL_TEST_SUITE: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/openpassportv2' }}
|
||||
run: yarn test
|
||||
|
||||
- name: Run Tests (Common)
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,4 +4,5 @@ sdk/.env
|
||||
dist
|
||||
**/node_modules
|
||||
**/node_modules/
|
||||
showcase
|
||||
showcase
|
||||
.codegpt
|
||||
@@ -7,6 +7,7 @@
|
||||
| nodejs | > v18 | [Install nodejs](https://nodejs.org/) |
|
||||
| circom | Latest | [Install circom](https://docs.circom.io/) |
|
||||
| snarkjs | Latest | [Install snarkjs](https://github.com/iden3/snarkjs) |
|
||||
| watchman | Latest | [Install watchman](https://facebook.github.io/watchman/) |
|
||||
|
||||
|
||||
### Android
|
||||
|
||||
@@ -85,8 +85,8 @@ android {
|
||||
applicationId "com.proofofpassportapp"
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 15
|
||||
versionName "1.4"
|
||||
versionCode 16
|
||||
versionName "1.5"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags += "-fexceptions -frtti -std=c++11"
|
||||
|
||||
@@ -2,5 +2,13 @@ module.exports = {
|
||||
presets: ['module:@react-native/babel-preset'],
|
||||
plugins: [
|
||||
["@babel/plugin-transform-private-methods", { "loose": true }],
|
||||
["module:react-native-dotenv", {
|
||||
"moduleName": "@env",
|
||||
"path": ".env",
|
||||
"blacklist": null,
|
||||
"whitelist": null,
|
||||
"safe": false,
|
||||
"allowUndefined": true
|
||||
}]
|
||||
],
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
1686F0E02C500FBD00841CDE /* QRScannerBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 1686F0DF2C500FBD00841CDE /* QRScannerBridge.m */; };
|
||||
16E6646E2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16E6646D2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift */; };
|
||||
16E884A52C5BD764003B7125 /* passport.json in Resources */ = {isa = PBXBuildFile; fileRef = 16E884A42C5BD764003B7125 /* passport.json */; };
|
||||
205310F3BECB4ECF3B41887C /* Pods_OpenPassport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A19556C626C22D40B7D18E23 /* Pods_OpenPassport.framework */; };
|
||||
1B904271B8E1DB8434EF0613 /* Pods_OpenPassport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3435ED6D988B5E2DE0DE8101 /* Pods_OpenPassport.framework */; };
|
||||
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
|
||||
905B70052A72767900AFA232 /* PassportReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 905B70042A72767900AFA232 /* PassportReader.swift */; };
|
||||
905B70072A72774000AFA232 /* PassportReader.m in Sources */ = {isa = PBXBuildFile; fileRef = 905B70062A72774000AFA232 /* PassportReader.m */; };
|
||||
@@ -112,14 +112,14 @@
|
||||
169349842CC694DA00166F21 /* OpenPassportDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = OpenPassportDebug.entitlements; path = OpenPassport/OpenPassportDebug.entitlements; sourceTree = "<group>"; };
|
||||
16E6646D2B8D292500FDD6A0 /* QKMRZScannerViewRepresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QKMRZScannerViewRepresentable.swift; sourceTree = "<group>"; };
|
||||
16E884A42C5BD764003B7125 /* passport.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = passport.json; sourceTree = "<group>"; };
|
||||
7C737C07B2C3788F9AB02DE4 /* Pods-OpenPassport.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenPassport.release.xcconfig"; path = "Target Support Files/Pods-OpenPassport/Pods-OpenPassport.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3435ED6D988B5E2DE0DE8101 /* Pods_OpenPassport.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OpenPassport.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = OpenPassport/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
905B70032A72767800AFA232 /* OpenPassport-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenPassport-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
905B70042A72767900AFA232 /* PassportReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassportReader.swift; sourceTree = "<group>"; };
|
||||
905B70062A72774000AFA232 /* PassportReader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PassportReader.m; sourceTree = "<group>"; };
|
||||
905B70082A729CD400AFA232 /* OpenPassport.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = OpenPassport.entitlements; path = OpenPassport/OpenPassport.entitlements; sourceTree = "<group>"; };
|
||||
A19556C626C22D40B7D18E23 /* Pods_OpenPassport.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OpenPassport.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C9DDA5F7441C6B4DEC17FCC9 /* Pods-OpenPassport.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenPassport.debug.xcconfig"; path = "Target Support Files/Pods-OpenPassport/Pods-OpenPassport.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
A239B1BBD7EF208EB51EF7DE /* Pods-OpenPassport.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenPassport.release.xcconfig"; path = "Target Support Files/Pods-OpenPassport/Pods-OpenPassport.release.xcconfig"; sourceTree = "<group>"; };
|
||||
BB9316819FB038104D42933E /* Pods-OpenPassport.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenPassport.debug.xcconfig"; path = "Target Support Files/Pods-OpenPassport/Pods-OpenPassport.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
E56E082698598B41447667BB /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = OpenPassport/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
/* End PBXFileReference section */
|
||||
@@ -140,7 +140,7 @@
|
||||
05D985F62BB331AB00F58EEA /* libfr.a in Frameworks */,
|
||||
167D934A2C91D2EA00530E6B /* libwitnesscalc_prove_rsa_65537_sha256.a in Frameworks */,
|
||||
167D93462C91B1E100530E6B /* libwitnesscalc_register_rsa_65537_sha1.a in Frameworks */,
|
||||
205310F3BECB4ECF3B41887C /* Pods_OpenPassport.framework in Frameworks */,
|
||||
1B904271B8E1DB8434EF0613 /* Pods_OpenPassport.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -227,7 +227,7 @@
|
||||
0569F35E2BBC98C9006670BD /* libfq.a */,
|
||||
0569F35A2BBC900D006670BD /* librapidsnark.a */,
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
A19556C626C22D40B7D18E23 /* Pods_OpenPassport.framework */,
|
||||
3435ED6D988B5E2DE0DE8101 /* Pods_OpenPassport.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -274,8 +274,8 @@
|
||||
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C9DDA5F7441C6B4DEC17FCC9 /* Pods-OpenPassport.debug.xcconfig */,
|
||||
7C737C07B2C3788F9AB02DE4 /* Pods-OpenPassport.release.xcconfig */,
|
||||
BB9316819FB038104D42933E /* Pods-OpenPassport.debug.xcconfig */,
|
||||
A239B1BBD7EF208EB51EF7DE /* Pods-OpenPassport.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
@@ -287,15 +287,15 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "OpenPassport" */;
|
||||
buildPhases = (
|
||||
17F3EE4BABFEFEDC3C2AD3FC /* [CP] Check Pods Manifest.lock */,
|
||||
62212FE980074600640A3F2F /* [CP] Check Pods Manifest.lock */,
|
||||
FD10A7F022414F080027D42C /* Start Packager */,
|
||||
13B07F871A680F5B00A75B9A /* Sources */,
|
||||
13B07F8C1A680F5B00A75B9A /* Frameworks */,
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
054340D12C71B2980014B445 /* Embed App Clips */,
|
||||
A032F3F676B35028E7879043 /* [CP] Embed Pods Frameworks */,
|
||||
C35A2C941C33076C64ACA128 /* [CP] Copy Pods Resources */,
|
||||
19B6B230BF58128B7603B834 /* [CP] Embed Pods Frameworks */,
|
||||
CCF107224BF9CF7E8A4F57B7 /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -369,7 +369,24 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
|
||||
};
|
||||
17F3EE4BABFEFEDC3C2AD3FC /* [CP] Check Pods Manifest.lock */ = {
|
||||
19B6B230BF58128B7603B834 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-OpenPassport/Pods-OpenPassport-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-OpenPassport/Pods-OpenPassport-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OpenPassport/Pods-OpenPassport-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
62212FE980074600640A3F2F /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -391,24 +408,7 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
A032F3F676B35028E7879043 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-OpenPassport/Pods-OpenPassport-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-OpenPassport/Pods-OpenPassport-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-OpenPassport/Pods-OpenPassport-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
C35A2C941C33076C64ACA128 /* [CP] Copy Pods Resources */ = {
|
||||
CCF107224BF9CF7E8A4F57B7 /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
@@ -492,7 +492,7 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
13B07F941A680F5B00A75B9A /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = C9DDA5F7441C6B4DEC17FCC9 /* Pods-OpenPassport.debug.xcconfig */;
|
||||
baseConfigurationReference = BB9316819FB038104D42933E /* Pods-OpenPassport.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
@@ -500,7 +500,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = OpenPassport/OpenPassportDebug.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 66;
|
||||
CURRENT_PROJECT_VERSION = 67;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 5B29R5LYHQ;
|
||||
ENABLE_BITCODE = NO;
|
||||
@@ -615,7 +615,7 @@
|
||||
"$(PROJECT_DIR)",
|
||||
"$(PROJECT_DIR)/MoproKit/Libs",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.9;
|
||||
MARKETING_VERSION = 2.0.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
@@ -633,13 +633,13 @@
|
||||
};
|
||||
13B07F951A680F5B00A75B9A /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7C737C07B2C3788F9AB02DE4 /* Pods-OpenPassport.release.xcconfig */;
|
||||
baseConfigurationReference = A239B1BBD7EF208EB51EF7DE /* Pods-OpenPassport.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = OpenPassport/OpenPassport.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 66;
|
||||
CURRENT_PROJECT_VERSION = 67;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = 5B29R5LYHQ;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@@ -753,7 +753,7 @@
|
||||
"$(PROJECT_DIR)",
|
||||
"$(PROJECT_DIR)/MoproKit/Libs",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.9;
|
||||
MARKETING_VERSION = 2.0.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
"-ObjC",
|
||||
|
||||
@@ -47,10 +47,17 @@ target 'OpenPassport' do
|
||||
post_install do |installer|
|
||||
installer.generated_projects.each do |project|
|
||||
project.targets.each do |target|
|
||||
if target.name == 'RNZipArchive'
|
||||
target.source_build_phase.files.each do |file|
|
||||
if file.settings && file.settings['COMPILER_FLAGS']
|
||||
file.settings['COMPILER_FLAGS'] = ''
|
||||
end
|
||||
end
|
||||
end
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
|
||||
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION']
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1813,8 +1813,8 @@ SPEC CHECKSUMS:
|
||||
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
|
||||
SwiftQRScanner: e85a25f9b843e9231dab89a96e441472fe54a724
|
||||
SwiftyTesseract: 1f3d96668ae92dc2208d9842c8a59bea9fad2cbb
|
||||
Yoga: b05994d1933f507b0a28ceaa4fdb968dc18da178
|
||||
Yoga: a9ef4f5c2cd79ad812110525ef61048be6a582a4
|
||||
|
||||
PODFILE CHECKSUM: fff5f0fc97e17fb53d7fd9198944714a37fed0a6
|
||||
PODFILE CHECKSUM: cc6778e0dcd4c510b705f4dc458411547dc1d00c
|
||||
|
||||
COCOAPODS: 1.15.2
|
||||
COCOAPODS: 1.16.2
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
"@tamagui/lucide-icons": "1.110.0",
|
||||
"@tamagui/toast": "1.110.0",
|
||||
"@tamagui/types": "1.110.0",
|
||||
"@types/msgpack-lite": "^0.1.11",
|
||||
"@types/pako": "^2.0.3",
|
||||
"axios": "^1.6.3",
|
||||
"buffer": "^6.0.3",
|
||||
"burnt": "^0.12.2",
|
||||
@@ -66,7 +64,9 @@
|
||||
"@tsconfig/react-native": "^3.0.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/msgpack-lite": "^0.1.11",
|
||||
"@types/node-forge": "^1.3.3",
|
||||
"@types/pako": "^2.0.3",
|
||||
"@types/react": "^18.2.6",
|
||||
"@types/react-native-dotenv": "^0.2.0",
|
||||
"@types/react-test-renderer": "^18.0.0",
|
||||
@@ -76,7 +76,7 @@
|
||||
"jest": "^29.6.3",
|
||||
"metro-react-native-babel-preset": "0.76.7",
|
||||
"prettier": "2.8.8",
|
||||
"react-native-dotenv": "^3.4.9",
|
||||
"react-native-dotenv": "^3.4.11",
|
||||
"react-test-renderer": "18.3.1",
|
||||
"typescript": "5.0.4"
|
||||
},
|
||||
|
||||
@@ -36,9 +36,9 @@ const MockDataScreen: React.FC<MockDataScreenProps> = ({
|
||||
|
||||
const { toast } = useNavigationStore();
|
||||
const signatureAlgorithmToStrictSignatureAlgorithm = {
|
||||
"rsa sha256": "rsa_sha256",
|
||||
"rsa sha1": "rsa_sha1",
|
||||
"rsapss sha256": "rsapss_sha256"
|
||||
"rsa sha256": "rsa_sha256_65537_2048",
|
||||
"rsa sha1": "rsa_sha1_65537_2048",
|
||||
"rsapss sha256": "rsapss_sha256_65537_2048"
|
||||
} as const;
|
||||
|
||||
const handleGenerate = useCallback(async () => {
|
||||
|
||||
@@ -9,12 +9,13 @@ import { DisclosureOptions, OpenPassportApp } from '../../../common/src/utils/ap
|
||||
import CustomButton from '../components/CustomButton';
|
||||
import { generateProof } from '../utils/prover';
|
||||
import io, { Socket } from 'socket.io-client';
|
||||
import { getCircuitName, parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
|
||||
import { getCircuitNameOld, parseCertificateSimple } from '../../../common/src/utils/certificate_parsing/parseCertificateSimple';
|
||||
import { CircuitName } from '../utils/zkeyDownload';
|
||||
import { generateCircuitInputsInApp } from '../utils/generateInputsInApp';
|
||||
import { buildAttestation } from '../../../common/src/utils/openPassportAttestation';
|
||||
import { generateCircuitInputsDSC, getCSCAFromSKI } from '../../../common/src/utils/csca';
|
||||
import { sendCSCARequest } from '../../../common/src/utils/csca';
|
||||
import { parsePassportData } from '../../../common/src/utils/parsePassportData';
|
||||
|
||||
interface ProveScreenProps {
|
||||
setSheetRegisterIsOpen: (value: boolean) => void;
|
||||
@@ -43,9 +44,10 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
|
||||
|
||||
const [socket, setSocket] = useState<Socket | null>(null);
|
||||
const [isConnecting, setIsConnecting] = useState(false);
|
||||
const { signatureAlgorithm, hashFunction, authorityKeyIdentifier } = parseCertificate(passportData.dsc);
|
||||
const { signatureAlgorithm, authorityKeyIdentifier } = parseCertificateSimple(passportData.dsc);
|
||||
const parsedPassportData = parsePassportData(passportData);
|
||||
const { secret, dscSecret } = useUserStore.getState();
|
||||
const circuitName = getCircuitName(selectedApp.mode, signatureAlgorithm, hashFunction);
|
||||
const circuitName = getCircuitNameOld(selectedApp.mode, signatureAlgorithm, parsedPassportData.signedAttrHashFunction);
|
||||
|
||||
const waitForSocketConnection = (socket: Socket): Promise<void> => {
|
||||
return new Promise((resolve) => {
|
||||
@@ -165,18 +167,18 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
|
||||
)
|
||||
]);
|
||||
const cscaPem = getCSCAFromSKI(authorityKeyIdentifier, DEVELOPMENT_MODE);
|
||||
const { signatureAlgorithm: signatureAlgorithmDsc } = parseCertificate(cscaPem);
|
||||
const { signatureAlgorithm: signatureAlgorithmDsc } = parseCertificateSimple(cscaPem);
|
||||
attestation = buildAttestation({
|
||||
mode: selectedApp.mode,
|
||||
proof: proof.proof,
|
||||
publicSignals: proof.publicSignals,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
hashFunction: hashFunction,
|
||||
hashFunction: parsedPassportData.signedAttrHashFunction,
|
||||
userIdType: selectedApp.userIdType,
|
||||
dscProof: (dscProof as any).proof,
|
||||
dscPublicSignals: (dscProof as any).pub_signals,
|
||||
signatureAlgorithmDsc: signatureAlgorithmDsc,
|
||||
hashFunctionDsc: hashFunction,
|
||||
hashFunctionDsc: parsedPassportData.signedAttrHashFunction,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
@@ -190,7 +192,7 @@ const ProveScreen: React.FC<ProveScreenProps> = ({ setSheetRegisterIsOpen }) =>
|
||||
proof: proof.proof,
|
||||
publicSignals: proof.publicSignals,
|
||||
signatureAlgorithm: signatureAlgorithm,
|
||||
hashFunction: hashFunction,
|
||||
hashFunction: parsedPassportData.signedAttrHashFunction,
|
||||
dsc: passportData.dsc,
|
||||
});
|
||||
break;
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import React from 'react';
|
||||
import { YStack, Text, XStack, Separator } from 'tamagui';
|
||||
import { YStack, Text, XStack, Separator, ScrollView } from 'tamagui';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import { textBlack, separatorColor } from '../utils/colors';
|
||||
import { findSubarrayIndex } from '../../../common/src/utils/utils';
|
||||
import { PassportData } from '../../../common/src/utils/types';
|
||||
import { hash } from '../../../common/src/utils/utils';
|
||||
import { parseCertificate } from '../../../common/src/utils/certificates/handleCertificate';
|
||||
import { parsePassportData } from '../../../common/src/utils/parsePassportData';
|
||||
|
||||
const UserInfo: React.FC = () => {
|
||||
const { passportData } = useUserStore();
|
||||
const { eContent, signedAttr, dg1Hash, dgPresents } = passportData as PassportData;
|
||||
const dg1HashOffset = dg1Hash ? findSubarrayIndex(eContent, dg1Hash.map(byte => byte > 127 ? byte - 256 : byte)) : undefined;
|
||||
const passportMetaData = passportData ? parsePassportData(passportData) : null;
|
||||
|
||||
const InfoRow = ({ label, value }: { label: string; value: string | number }) => (
|
||||
<XStack py="$2" justifyContent="space-between">
|
||||
@@ -19,70 +15,61 @@ const UserInfo: React.FC = () => {
|
||||
</XStack>
|
||||
);
|
||||
|
||||
function findHashSizeOfEContent(eContent: number[], signedAttr: number[]) {
|
||||
const allHashes = ['sha512', 'sha384', 'sha256', 'sha1'];
|
||||
for (const hashFunction of allHashes) {
|
||||
const hashValue = hash(hashFunction, eContent);
|
||||
const hashOffset = findSubarrayIndex(signedAttr, hashValue);
|
||||
if (hashOffset !== -1) {
|
||||
return { hashFunction, offset: hashOffset };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { hashFunction: eContentHashFunction, offset: eContentHashOffset } = findHashSizeOfEContent(eContent, signedAttr) || { hashFunction: '', offset: 0 };
|
||||
const dscHashFunction = parseCertificate(passportData?.dsc || '').hashFunction;
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<YStack f={1} p="$0" gap="$2" jc="flex-start" mt="$10">
|
||||
<Text fontSize="$8" color={textBlack} mb="$4">Passport Data Info</Text>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<ScrollView>
|
||||
<YStack f={1} p="$0" gap="$2" jc="flex-start" py="$2" >
|
||||
<Text fontSize="$8" color={textBlack} mb="$4">Passport Data Info</Text>
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow
|
||||
label="Data Groups"
|
||||
value={passportData?.dgPresents?.toString().split(',').map(item => item.replace('DG', '')).join(',') || 'None'}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow label="Data Groups" value={passportMetaData?.dataGroups || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow
|
||||
label="DG1 Hash Size"
|
||||
value={`${passportData?.dg1Hash?.length || 0} ${passportData?.dg1Hash?.length === 32 ? '(sha256)' : passportData?.dg1Hash?.length === 20 ? '(sha1)' : passportData?.dg1Hash?.length === 48 ? '(sha384)' : passportData?.dg1Hash?.length === 64 ? '(sha512)' : ''}`}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow
|
||||
label="DG1 Hash Offset"
|
||||
value={dg1HashOffset || 0}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow label="DG1 Hash Function" value={passportMetaData?.dg1HashFunction || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow
|
||||
label="eContent Size"
|
||||
value={passportData?.eContent?.length || 0}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow
|
||||
label="eContent Hash Function"
|
||||
value={eContentHashFunction}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow
|
||||
label="eContent Hash Offset"
|
||||
value={eContentHashOffset}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow label="DG1 Hash Offset" value={passportMetaData?.dg1HashOffset || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow
|
||||
label="Signed Attributes Size"
|
||||
value={passportData?.signedAttr?.length || 0}
|
||||
/>
|
||||
<Separator borderColor={separatorColor} />
|
||||
<InfoRow
|
||||
label="Signed Attributes Hash Function"
|
||||
value={dscHashFunction}
|
||||
/>
|
||||
</YStack>
|
||||
<InfoRow label="eContent Size" value={passportMetaData?.eContentSize || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="eContent Hash Function" value={passportMetaData?.eContentHashFunction || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="eContent Hash Offset" value={passportMetaData?.eContentHashOffset || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="Signed Attributes Size" value={passportMetaData?.signedAttrSize || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="Signed Attributes Hash Function" value={passportMetaData?.signedAttrHashFunction || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="Signature Algorithm" value={passportMetaData?.signatureAlgorithm || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="Signature Algorithm Details" value={passportMetaData?.curveOrExponent || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="Signature Algorithm Bits" value={passportMetaData?.signatureAlgorithmBits || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="CSCA Found" value={passportMetaData?.cscaFound ? 'Yes' : 'No'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="CSCA Hash Function" value={passportMetaData?.cscaHashFunction || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="CSCA Signature Algorithm" value={passportMetaData?.cscaSignature || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="CSCA Signature Algorithm Details" value={passportMetaData?.cscaCurveOrExponent || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
|
||||
<InfoRow label="CSCA Signature Algorithm Bits" value={passportMetaData?.cscaSignatureAlgorithmBits || 'None'} />
|
||||
<Separator borderColor={separatorColor} />
|
||||
</YStack>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ interface UserState {
|
||||
passportNumber: string
|
||||
dateOfBirth: string
|
||||
dateOfExpiry: string
|
||||
countryCode: string
|
||||
registered: boolean
|
||||
passportData: PassportData | null
|
||||
secret: string
|
||||
@@ -39,6 +40,7 @@ const useUserStore = create<UserState>((set, get) => ({
|
||||
passportNumber: DEFAULT_PNUMBER ?? "",
|
||||
dateOfBirth: DEFAULT_DOB ?? "",
|
||||
dateOfExpiry: DEFAULT_DOE ?? "",
|
||||
countryCode: "",
|
||||
dscSecret: null,
|
||||
registered: false,
|
||||
passportData: null,
|
||||
|
||||
@@ -46,7 +46,7 @@ export async function contribute(passportData: any): Promise<void> {
|
||||
|
||||
console.log("Data to be sent:", JSON.stringify(data));
|
||||
|
||||
const response = await axios.post('https://contribute.proofofpassport.com', {
|
||||
const response = await axios.post('https://contribute.openpassport.app', {
|
||||
nullifier: forge.md.sha256.create().update(passportData.encryptedDigest.toString()).digest().toHex(),
|
||||
data: data
|
||||
});
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Buffer } from 'buffer';
|
||||
import * as amplitude from '@amplitude/analytics-react-native';
|
||||
import useUserStore from '../stores/userStore';
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { parsePassportData } from './parsePassportData';
|
||||
|
||||
export const scan = async (setModalProofStep: (modalProofStep: number) => void) => {
|
||||
const {
|
||||
@@ -177,17 +178,17 @@ const handleResponseIOS = async (
|
||||
|
||||
const encryptedDigestArray = Array.from(Buffer.from(signatureBase64, 'base64')).map(byte => byte > 127 ? byte - 256 : byte);
|
||||
|
||||
amplitude.track('nfc_response_parsed', {
|
||||
dataGroupsPresent: parsed?.dataGroupsPresent,
|
||||
eContentLength: signedEContentArray?.length,
|
||||
concatenatedDataHashesLength: concatenatedDataHashesArraySigned?.length,
|
||||
encryptedDigestLength: encryptedDigestArray?.length,
|
||||
activeAuthenticationPassed: parsed?.activeAuthenticationPassed,
|
||||
isPACESupported: parsed?.isPACESupported,
|
||||
isChipAuthenticationSupported: parsed?.isChipAuthenticationSupported,
|
||||
encapsulatedContentDigestAlgorithm: parsed?.encapsulatedContentDigestAlgorithm,
|
||||
dsc: pem,
|
||||
});
|
||||
// amplitude.track('nfc_response_parsed', {
|
||||
// dataGroupsPresent: parsed?.dataGroupsPresent,
|
||||
// eContentLength: signedEContentArray?.length,
|
||||
// concatenatedDataHashesLength: concatenatedDataHashesArraySigned?.length,
|
||||
// encryptedDigestLength: encryptedDigestArray?.length,
|
||||
// activeAuthenticationPassed: parsed?.activeAuthenticationPassed,
|
||||
// isPACESupported: parsed?.isPACESupported,
|
||||
// isChipAuthenticationSupported: parsed?.isChipAuthenticationSupported,
|
||||
// encapsulatedContentDigestAlgorithm: parsed?.encapsulatedContentDigestAlgorithm,
|
||||
// dsc: pem,
|
||||
// });
|
||||
|
||||
const passportData = {
|
||||
mrz,
|
||||
@@ -201,6 +202,8 @@ const handleResponseIOS = async (
|
||||
photoBase64: "data:image/jpeg;base64," + parsed.passportPhoto,
|
||||
mockUser: false
|
||||
};
|
||||
const parsedPassportData = parsePassportData(passportData);
|
||||
amplitude.track('nfc_response_parsed', parsedPassportData);
|
||||
|
||||
try {
|
||||
useUserStore.getState().registerPassportData(passportData)
|
||||
@@ -280,16 +283,18 @@ const handleResponseAndroid = async (
|
||||
console.log("encapContent", encapContent)
|
||||
console.log("documentSigningCertificate", documentSigningCertificate)
|
||||
|
||||
amplitude.track('nfc_response_parsed', {
|
||||
dataGroupHashesLength: passportData?.eContent?.length,
|
||||
eContentLength: passportData?.eContent?.length,
|
||||
encryptedDigestLength: passportData?.encryptedDigest?.length,
|
||||
digestAlgorithm: digestAlgorithm,
|
||||
signerInfoDigestAlgorithm: signerInfoDigestAlgorithm,
|
||||
digestEncryptionAlgorithm: digestEncryptionAlgorithm,
|
||||
dsc: pem,
|
||||
mockUser: false
|
||||
});
|
||||
const parsedPassportData = parsePassportData(passportData);
|
||||
amplitude.track('nfc_response_parsed', parsedPassportData);
|
||||
// amplitude.track('nfc_response_parsed', {
|
||||
// dataGroupHashesLength: passportData?.eContent?.length,
|
||||
// eContentLength: passportData?.eContent?.length,
|
||||
// encryptedDigestLength: passportData?.encryptedDigest?.length,
|
||||
// digestAlgorithm: digestAlgorithm,
|
||||
// signerInfoDigestAlgorithm: signerInfoDigestAlgorithm,
|
||||
// digestEncryptionAlgorithm: digestEncryptionAlgorithm,
|
||||
// dsc: pem,
|
||||
// mockUser: false
|
||||
// });
|
||||
|
||||
try {
|
||||
await useUserStore.getState().registerPassportData(passportData)
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { NativeModules, Platform, Linking } from "react-native";
|
||||
// import { AppType, reconstructAppType } from "../../../common/src/utils/appType";
|
||||
import useNavigationStore from '../stores/navigationStore';
|
||||
import { getCircuitName, parseDSC } from "../../../common/src/utils/certificates/handleCertificate";
|
||||
import useUserStore from "../stores/userStore";
|
||||
import { downloadZkey } from "./zkeyDownload";
|
||||
import msgpack from "msgpack-lite";
|
||||
import pako from "pako";
|
||||
import { Mode, OpenPassportApp } from "../../../common/src/utils/appType";
|
||||
|
||||
import { getCircuitNameOld, parseCertificateSimple } from "../../../common/src/utils/certificate_parsing/parseCertificateSimple";
|
||||
const parseUrlParams = (url: string): Map<string, string> => {
|
||||
const [, queryString] = url.split('?');
|
||||
const params = new Map<string, string>();
|
||||
@@ -98,11 +97,11 @@ const handleQRCodeScan = (result: string, toast: any, setSelectedApp: any, setSe
|
||||
const openPassportApp: OpenPassportApp = unpackedData;
|
||||
setSelectedApp(openPassportApp);
|
||||
|
||||
const sigAlgName = parseDSC(dsc);
|
||||
const parsedDsc = parseCertificateSimple(dsc);
|
||||
|
||||
const circuitName = openPassportApp.mode === 'vc_and_disclose'
|
||||
? 'vc_and_disclose'
|
||||
: getCircuitName("prove" as Mode, sigAlgName.signatureAlgorithm, sigAlgName.hashFunction);
|
||||
: getCircuitNameOld("prove" as Mode, parsedDsc.signatureAlgorithm, parsedDsc.hashAlgorithm);
|
||||
downloadZkey(circuitName as any);
|
||||
|
||||
setSelectedTab("prove");
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { countryCodes } from "../../../common/src/constants/constants";
|
||||
import { Proof } from "../../../common/src/utils/types";
|
||||
import { getCountryCodeFromMrz } from "./parsePassportData";
|
||||
|
||||
// The actual parsing would depend on the standard being used (TD1, TD2, TD3, MRVA, MRVB).
|
||||
export function extractMRZInfo(mrzString: string) {
|
||||
@@ -18,7 +19,7 @@ export function extractMRZInfo(mrzString: string) {
|
||||
return {
|
||||
documentNumber,
|
||||
birthDate,
|
||||
expiryDate
|
||||
expiryDate,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -48,7 +48,6 @@ template VC_AND_DISCLOSE( nLevels,FORBIDDEN_COUNTRIES_LIST_LENGTH) {
|
||||
component poseidon_nullifier = PoseidonHash(2);
|
||||
poseidon_nullifier.in[0] <== secret;
|
||||
poseidon_nullifier.in[1] <== scope;
|
||||
poseidon_nullifier.dummy <== 0;
|
||||
signal output nullifier <== poseidon_nullifier.out;
|
||||
signal output revealedData_packed[3] <== disclose.revealedData_packed;
|
||||
signal output older_than[2] <== disclose.older_than;
|
||||
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_dsc.circom";
|
||||
|
||||
component main { public [ merkle_root ] } = OPENPASSPORT_DSC(11, 64, 32, 64, 64, 1664, 256, 12);
|
||||
component main { public [ merkle_root ] } = OPENPASSPORT_DSC(11, 120, 35, 120, 35, 1664, 256, 12);
|
||||
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_dsc.circom";
|
||||
|
||||
component main { public [ merkle_root ] } = OPENPASSPORT_DSC(10, 64, 32, 64, 64, 1664, 256, 12);
|
||||
component main { public [ merkle_root ] } = OPENPASSPORT_DSC(10, 120, 35, 120, 35, 1664, 256, 12);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_dsc.circom";
|
||||
|
||||
component main { public [ merkle_root ] } = OPENPASSPORT_DSC(12, 64, 32, 64, 64, 1664, 256, 12);
|
||||
component main { public [ merkle_root ] } = OPENPASSPORT_DSC(12, 120, 35, 120, 35, 1664, 256, 12);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../utils/circomlib/bitify/bitify.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "../utils/circomlib/hasher/shaBytes/shaBytesDynamic.circom";
|
||||
include "../utils/circomlib/bitify/comparators.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../utils/circomlib/hasher/hash.circom";
|
||||
include "../utils/circomlib/merkle-trees/binary-merkle-root.circom";
|
||||
include "../utils/passport/customHashers.circom";
|
||||
include "../utils/passport/signatureAlgorithm.circom";
|
||||
include "../utils/passport/signatureVerifier.circom";
|
||||
include "../utils/circomlib/utils/bytes.circom";
|
||||
include "@zk-email/circuits/utils/bytes.circom";
|
||||
|
||||
|
||||
template OPENPASSPORT_DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_cert_bytes, dscPubkeyBytesLength, nLevels) {
|
||||
@@ -34,7 +34,6 @@ template OPENPASSPORT_DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_
|
||||
signal input path[nLevels];
|
||||
signal input siblings[nLevels];
|
||||
|
||||
signal dummy <== 0;
|
||||
|
||||
// leaf
|
||||
signal leaf <== LeafHasher(kScaled)(csca_pubKey, signatureAlgorithm);
|
||||
@@ -45,7 +44,7 @@ template OPENPASSPORT_DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_
|
||||
// verify certificate signature
|
||||
signal hashedCertificate[hashLength] <== ShaBytesDynamic(hashLength, max_cert_bytes)(raw_dsc_cert, raw_dsc_cert_padded_bytes);
|
||||
|
||||
SignatureVerifier(signatureAlgorithm, n_csca, k_csca)(hashedCertificate, csca_pubKey, signature, dummy);
|
||||
SignatureVerifier(signatureAlgorithm, n_csca, k_csca)(hashedCertificate, csca_pubKey, signature);
|
||||
|
||||
// verify DSC csca_pubKey
|
||||
component shiftLeft = VarShiftLeft(max_cert_bytes, dscPubkeyBytesLength); // use select subarray for dscPubKey variable length
|
||||
@@ -59,6 +58,6 @@ template OPENPASSPORT_DSC(signatureAlgorithm, n_dsc, k_dsc, n_csca, k_csca, max_
|
||||
|
||||
// blinded dsc commitment
|
||||
signal pubkeyHash <== CustomHasher(k_dsc)(dsc_pubKey);
|
||||
signal output blinded_dsc_commitment <== PoseidonHash(2)([secret, pubkeyHash], 0);
|
||||
signal output blinded_dsc_commitment <== PoseidonHash(2)([secret, pubkeyHash]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date ] } = OPENPASSPORT_PROVE(13, 64, 32, 384, 192, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(16, 96, 32, 384, 192, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(17, 64, 64, 384, 192, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(4, 64, 32, 384, 192, 20);
|
||||
@@ -1,5 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(12, 64, 64, 384, 192, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(8, 64, 4, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(160, 160, 7, 64, 4, 320, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(3, 64, 32, 320, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(160, 160 , 3, 64, 32, 320, 128, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(160, 256 , 1, 120, 35, 320, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(7, 64, 4, 320, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 8, 64, 4, 448, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date ] } = OPENPASSPORT_PROVE(19, 96, 32, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date ] } = OPENPASSPORT_PROVE(256, 256, 13, 120, 35, 448, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date ] } = OPENPASSPORT_PROVE(14, 96, 32, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date ] } = OPENPASSPORT_PROVE(256, 256, 14, 96, 32, 448, 128, 20);
|
||||
@@ -2,4 +2,4 @@ pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(1, 64, 32, 384, 192, 20);
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256 ,256 ,1, 120, 35, 448, 128, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256,256, 17, 120, 35, 448, 128, 20);
|
||||
@@ -0,0 +1,5 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../openpassport_prove.circom";
|
||||
|
||||
component main { public [ scope, user_identifier, current_date] } = OPENPASSPORT_PROVE(256, 256, 12, 120, 35, 448, 128, 20);
|
||||
@@ -10,7 +10,7 @@ include "../utils/passport/disclose/disclose.circom";
|
||||
include "../utils/passport/disclose/proveCountryIsNotInList.circom";
|
||||
include "../utils/passport/ofac/ofac_name.circom";
|
||||
|
||||
template OPENPASSPORT_PROVE(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN, FORBIDDEN_COUNTRIES_LIST_LENGTH) {
|
||||
template OPENPASSPORT_PROVE(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN, FORBIDDEN_COUNTRIES_LIST_LENGTH) {
|
||||
var kLengthFactor = getKLengthFactor(signatureAlgorithm);
|
||||
var kScaled = k * kLengthFactor;
|
||||
|
||||
@@ -47,7 +47,6 @@ template OPENPASSPORT_PROVE(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, M
|
||||
signal input secret;
|
||||
signal input dsc_secret;
|
||||
|
||||
signal dummy <== 0;
|
||||
|
||||
signal attestation_id <== 1;
|
||||
|
||||
@@ -59,7 +58,7 @@ template OPENPASSPORT_PROVE(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, M
|
||||
isWrongSelectorMode === 0;
|
||||
|
||||
// verify passport signature
|
||||
PassportVerifier(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN)(dg1,dg1_hash_offset, dg2_hash, eContent,eContent_padded_length, signed_attr, signed_attr_padded_length, signed_attr_econtent_hash_offset, pubKey, signature, dummy);
|
||||
PassportVerifier(DG_HASH_ALGO, ECONTENT_HASH_ALGO, signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, MAX_SIGNED_ATTR_PADDED_LEN)(dg1,dg1_hash_offset, dg2_hash, eContent,eContent_padded_length, signed_attr, signed_attr_padded_length, signed_attr_econtent_hash_offset, pubKey, signature);
|
||||
// verify passport is not expired
|
||||
component isValid = IsValid();
|
||||
isValid.currDate <== current_date;
|
||||
@@ -72,7 +71,6 @@ template OPENPASSPORT_PROVE(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, M
|
||||
component poseidon_hasher = PoseidonHash(2);
|
||||
poseidon_hasher.in[0] <== signatureHashed;
|
||||
poseidon_hasher.in[1] <== scope;
|
||||
poseidon_hasher.dummy <== 0;
|
||||
signal output nullifier <== poseidon_hasher.out;
|
||||
|
||||
// DISCLOSE (optional)
|
||||
@@ -116,6 +114,6 @@ template OPENPASSPORT_PROVE(signatureAlgorithm, n, k, MAX_ECONTENT_PADDED_LEN, M
|
||||
signal output commitment <== commitmentPrivate * selectorModeCommitment;
|
||||
// // blinded dsc commitment
|
||||
signal pubkeyHash <== CustomHasher(kScaled)(pubKey);
|
||||
signal blindedDscCommitmenPrivate <== PoseidonHash(2)([dsc_secret, pubkeyHash],0);
|
||||
signal blindedDscCommitmenPrivate <== PoseidonHash(2)([dsc_secret, pubkeyHash]);
|
||||
signal output blinded_dsc_commitment <== blindedDscCommitmenPrivate * selectorModeBlindedDscCommitment;
|
||||
}
|
||||
|
||||
72
circuits/circuits/removeDummy.py
Normal file
72
circuits/circuits/removeDummy.py
Normal file
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
def process_line(line):
|
||||
# Handle "+ dummy * dummy" pattern at the end (only lowercase, standalone 'dummy')
|
||||
line = re.sub(r'\s*\+\s*\bdummy\b\s*\*\s*\bdummy\b', '', line)
|
||||
|
||||
# Handle "dummy * dummy +" pattern at the start of expression (only lowercase, standalone 'dummy')
|
||||
line = re.sub(r'<==\s*\bdummy\b\s*\*\s*\bdummy\b\s*\+\s*', '<== ', line)
|
||||
|
||||
# If line starts with uppercase or contains 'template'
|
||||
if line[0].isupper() or 'template' in line.lower():
|
||||
# Remove ', dummy' or 'dummy,' pattern (only lowercase, standalone 'dummy')
|
||||
line = re.sub(r',\s*\bdummy\b(?![A-Za-z])', '', line)
|
||||
line = re.sub(r'\bdummy\b(?![A-Za-z]),', '', line)
|
||||
# Remove standalone 'dummy' (only lowercase)
|
||||
line = re.sub(r'\bdummy\b(?![A-Za-z])', '', line)
|
||||
return line
|
||||
# Handle function calls with dummy parameter
|
||||
elif '(' in line and ')' in line:
|
||||
# Remove ', dummy' before closing parenthesis (only lowercase, standalone 'dummy')
|
||||
line = re.sub(r',\s*\bdummy\b(?![A-Za-z])\s*\)', ')', line)
|
||||
return line
|
||||
# For other lines, if they contain standalone 'dummy' (lowercase only), return None to remove the entire line
|
||||
elif re.search(r'\bdummy\b(?![A-Za-z])', line):
|
||||
return None
|
||||
return line
|
||||
|
||||
def remove_dummy_lines(directory):
|
||||
# Walk through all directories and files
|
||||
for root, dirs, files in os.walk(directory):
|
||||
# Filter for .circom files
|
||||
for file in files:
|
||||
if file.endswith('.circom'):
|
||||
file_path = os.path.join(root, file)
|
||||
print(f"Processing: {file_path}")
|
||||
|
||||
# Read file content
|
||||
with open(file_path, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# Process lines
|
||||
new_lines = []
|
||||
lines_removed = 0
|
||||
for line in lines:
|
||||
processed_line = process_line(line)
|
||||
if processed_line is not None:
|
||||
new_lines.append(processed_line)
|
||||
else:
|
||||
lines_removed += 1
|
||||
|
||||
# If we found and modified/removed any lines
|
||||
if len(lines) != len(new_lines):
|
||||
print(f"Modified/Removed {lines_removed} lines containing 'dummy' in {file_path}")
|
||||
|
||||
# Write back the filtered content
|
||||
with open(file_path, 'w') as f:
|
||||
f.writelines(new_lines)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Get the current directory where the script is running
|
||||
current_dir = os.getcwd()
|
||||
|
||||
# Ask for confirmation
|
||||
print(f"This will process 'dummy' occurrences in .circom files in {current_dir} and its subdirectories.")
|
||||
confirm = input("Do you want to continue? (y/n): ")
|
||||
|
||||
if confirm.lower() == 'y':
|
||||
remove_dummy_lines(current_dir)
|
||||
print("Process completed!")
|
||||
else:
|
||||
print("Operation cancelled.")
|
||||
@@ -1,3 +1,3 @@
|
||||
pragma circom 2.1.9;
|
||||
include "../../disclose/proveCountryIsNotInList.circom";
|
||||
include "../../utils/passport/disclose/proveCountryIsNotInList.circom";
|
||||
component main { public [ forbidden_countries_list ] } = ProveCountryIsNotInList(20);
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom";
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
|
||||
template VerifyRsaPkcs1v1_5Tester() {
|
||||
signal input signature[32];
|
||||
signal input modulus[32];
|
||||
signal input message[32];
|
||||
signal input signature[35];
|
||||
signal input modulus[35];
|
||||
signal input message[35];
|
||||
|
||||
signal input dummy;
|
||||
|
||||
VerifyRsaPkcs1v1_5(3, 64, 32, 65537, 160)(signature, modulus, message, dummy);
|
||||
VerifyRsa65537Pkcs1v1_5(120, 35, 160)(signature, modulus, message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPkcs1v1_5Tester();
|
||||
@@ -1,15 +1,13 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom";
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsa3Pkcs1v1_5.circom";
|
||||
|
||||
template VerifyRsaPkcs1v1_5Tester() {
|
||||
signal input signature[32];
|
||||
signal input modulus[32];
|
||||
signal input message[32];
|
||||
signal input signature[35];
|
||||
signal input modulus[35];
|
||||
signal input message[35];
|
||||
|
||||
signal input dummy;
|
||||
|
||||
VerifyRsaPkcs1v1_5(13, 64, 32, 3, 256)(signature, modulus, message, dummy);
|
||||
VerifyRsa3Pkcs1v1_5(120, 35, 256)(signature, modulus, message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPkcs1v1_5Tester();
|
||||
@@ -1,15 +1,14 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom";
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
|
||||
template VerifyRsaPkcs1v1_5Tester() {
|
||||
signal input signature[32];
|
||||
signal input modulus[32];
|
||||
signal input message[32];
|
||||
signal input signature[35];
|
||||
signal input modulus[35];
|
||||
signal input message[35];
|
||||
|
||||
signal input dummy;
|
||||
|
||||
VerifyRsaPkcs1v1_5(1, 64, 32, 65537, 256)(signature, modulus, message, dummy);
|
||||
VerifyRsa65537Pkcs1v1_5(120, 35, 256)(signature, modulus, message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPkcs1v1_5Tester();
|
||||
@@ -1,15 +1,13 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom";
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
|
||||
template VerifyRsaPkcs1v1_5Tester() {
|
||||
signal input signature[32];
|
||||
signal input modulus[32];
|
||||
signal input message[32];
|
||||
signal input signature[35];
|
||||
signal input modulus[35];
|
||||
signal input message[35];
|
||||
|
||||
signal input dummy;
|
||||
|
||||
VerifyRsaPkcs1v1_5(14, 96, 32, 65537, 256)(signature, modulus, message, dummy);
|
||||
VerifyRsa65537Pkcs1v1_5(120, 35, 256)(signature, modulus, message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPkcs1v1_5Tester();
|
||||
@@ -1,15 +1,13 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom";
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
|
||||
template VerifyRsaPkcs1v1_5Tester() {
|
||||
signal input signature[64];
|
||||
signal input modulus[64];
|
||||
signal input message[64];
|
||||
signal input signature[35];
|
||||
signal input modulus[35];
|
||||
signal input message[35];
|
||||
|
||||
signal input dummy;
|
||||
|
||||
VerifyRsaPkcs1v1_5(10, 64, 64, 65537, 256)(signature, modulus, message, dummy);
|
||||
VerifyRsa65537Pkcs1v1_5(120, 35, 256)(signature, modulus, message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPkcs1v1_5Tester();
|
||||
@@ -1,15 +1,13 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsaPkcs1v1_5.circom";
|
||||
include "../../../utils/circomlib/signature/rsa/verifyRsa65537Pkcs1v1_5.circom";
|
||||
|
||||
template VerifyRsaPkcs1v1_5Tester() {
|
||||
signal input signature[64];
|
||||
signal input modulus[64];
|
||||
signal input message[64];
|
||||
signal input signature[35];
|
||||
signal input modulus[35];
|
||||
signal input message[35];
|
||||
|
||||
signal input dummy;
|
||||
|
||||
VerifyRsaPkcs1v1_5(15, 64, 64, 65537, 512)(signature, modulus, message, dummy);
|
||||
VerifyRsa65537Pkcs1v1_5(120, 35, 512)(signature, modulus, message);
|
||||
}
|
||||
|
||||
component main = VerifyRsaPkcs1v1_5Tester();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../bitify/comparators.circom";
|
||||
include "../bitify/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "./bigIntFunc.circom";
|
||||
include "./bigIntOverflow.circom";
|
||||
include "../int/arithmetic.circom";
|
||||
@@ -47,10 +47,9 @@ template BigAddNoCarry(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
out[i] <== in[0][i] + in[1][i] + dummy * dummy;
|
||||
out[i] <== in[0][i] + in[1][i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,11 +59,9 @@ template BigAdd(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER + 1];
|
||||
signal input dummy;
|
||||
|
||||
component bigAddNoCarry = BigAddNoCarry(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigAddNoCarry.in <== in;
|
||||
bigAddNoCarry.dummy <== dummy;
|
||||
|
||||
component num2bits[CHUNK_NUMBER];
|
||||
|
||||
@@ -75,16 +72,16 @@ template BigAdd(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
if (i == 0){
|
||||
num2bits[i].in <== bigAddNoCarry.out[i];
|
||||
} else {
|
||||
num2bits[i].in <== bigAddNoCarry.out[i] + num2bits[i - 1].out[CHUNK_SIZE] + dummy * dummy;
|
||||
num2bits[i].in <== bigAddNoCarry.out[i] + num2bits[i - 1].out[CHUNK_SIZE];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
if (i == 0) {
|
||||
out[i] <== bigAddNoCarry.out[i] - (num2bits[i].out[CHUNK_SIZE]) * (2 ** CHUNK_SIZE) + dummy * dummy;
|
||||
out[i] <== bigAddNoCarry.out[i] - (num2bits[i].out[CHUNK_SIZE]) * (2 ** CHUNK_SIZE);
|
||||
}
|
||||
else {
|
||||
out[i] <== bigAddNoCarry.out[i] - (num2bits[i].out[CHUNK_SIZE]) * (2 ** CHUNK_SIZE) + num2bits[i - 1].out[CHUNK_SIZE] + dummy * dummy;
|
||||
out[i] <== bigAddNoCarry.out[i] - (num2bits[i].out[CHUNK_SIZE]) * (2 ** CHUNK_SIZE) + num2bits[i - 1].out[CHUNK_SIZE];
|
||||
}
|
||||
}
|
||||
out[CHUNK_NUMBER] <== num2bits[CHUNK_NUMBER - 1].out[CHUNK_SIZE];
|
||||
@@ -97,7 +94,6 @@ template BigMultNoCarry(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
assert(CHUNK_SIZE <= 126);
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
signal output out[CHUNK_NUMBER * 2 - 1];
|
||||
|
||||
signal tmpMults[CHUNK_NUMBER][CHUNK_NUMBER];
|
||||
@@ -127,7 +123,7 @@ template BigMultNoCarry(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[i - j][j];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][i];
|
||||
@@ -137,7 +133,7 @@ template BigMultNoCarry(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[CHUNK_NUMBER - 1 - j][i + j - CHUNK_NUMBER + 1];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[CHUNK_NUMBER - 1 - j][i + j - CHUNK_NUMBER + 1] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[CHUNK_NUMBER - 1 - j][i + j - CHUNK_NUMBER + 1] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][2 * CHUNK_NUMBER - 2 - i];
|
||||
@@ -151,15 +147,12 @@ template BigMultNoCarry(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
template BigMult(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[CHUNK_NUMBER * 2];
|
||||
|
||||
component bigMultNoCarry = BigMultNoCarry(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigMultNoCarry.in <== in;
|
||||
bigMultNoCarry.dummy <== dummy;
|
||||
|
||||
component num2bits[CHUNK_NUMBER * 2 - 1];
|
||||
component bits2numOverflow[CHUNK_NUMBER * 2 - 1];
|
||||
@@ -179,7 +172,7 @@ template BigMult(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
if (i == 0){
|
||||
num2bits[i].in <== bigMultNoCarry.out[i];
|
||||
} else {
|
||||
num2bits[i].in <== dummy * dummy + bigMultNoCarry.out[i] + bits2numOverflow[i - 1].out;
|
||||
num2bits[i].in <== bigMultNoCarry.out[i] + bits2numOverflow[i - 1].out;
|
||||
}
|
||||
|
||||
bits2numOverflow[i] = Bits2Num(CHUNK_SIZE + ADDITIONAL_LEN);
|
||||
@@ -206,15 +199,12 @@ template BigMult(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
// use only for CHUNK_NUMBER == 2 ** x
|
||||
template BigMultOptimised(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input dummy;
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER * 2];
|
||||
|
||||
component karatsuba = KaratsubaNoCarry(CHUNK_NUMBER);
|
||||
karatsuba.in <== in;
|
||||
karatsuba.dummy <== dummy;
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
component getLastNBits[CHUNK_NUMBER * 2 - 1];
|
||||
component bits2Num[CHUNK_NUMBER * 2 - 1];
|
||||
@@ -245,9 +235,8 @@ template BigMod(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input base[CHUNK_NUMBER * 2];
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
var long_division[2][200] = long_div(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER, base, modulus);
|
||||
var long_division[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER, base, modulus);
|
||||
|
||||
signal output div[CHUNK_NUMBER + 1];
|
||||
signal output mod[CHUNK_NUMBER];
|
||||
@@ -265,7 +254,6 @@ template BigMod(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
multChecks.in1 <== div;
|
||||
multChecks.in2 <== modulus;
|
||||
multChecks.dummy <== dummy;
|
||||
|
||||
component greaterThan = BigGreaterThan(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
|
||||
@@ -279,7 +267,6 @@ template BigMod(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
bigAddCheck.in1 <== multChecks.out;
|
||||
bigAddCheck.in2 <== mod;
|
||||
bigAddCheck.dummy <== dummy;
|
||||
|
||||
|
||||
component smartEqual = SmartEqual(CHUNK_SIZE, CHUNK_NUMBER * 2 + 2);
|
||||
@@ -289,7 +276,6 @@ template BigMod(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
}
|
||||
smartEqual.in[1][CHUNK_NUMBER * 2] <== 0;
|
||||
smartEqual.in[1][CHUNK_NUMBER * 2 + 1] <== 0;
|
||||
smartEqual.dummy <== dummy;
|
||||
|
||||
smartEqual.out === 1;
|
||||
}
|
||||
@@ -300,17 +286,14 @@ template BigMod(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
template BigMultModP(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
signal input in[3][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
component bigMult = BigMultOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigMult.in[0] <== in[0];
|
||||
bigMult.in[1] <== in[1];
|
||||
bigMult.dummy <== dummy;
|
||||
|
||||
component bigMod = BigMod(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigMod.base <== bigMult.out;
|
||||
bigMod.modulus <== in[2];
|
||||
bigMod.dummy <== dummy;
|
||||
|
||||
out <== bigMod.mod;
|
||||
}
|
||||
@@ -321,17 +304,14 @@ template BigMultModP(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
template BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
signal input in[3][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
component bigMult = BigMult(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigMult.in[0] <== in[0];
|
||||
bigMult.in[1] <== in[1];
|
||||
bigMult.dummy <== dummy;
|
||||
|
||||
component bigMod = BigMod(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigMod.base <== bigMult.out;
|
||||
bigMod.modulus <== in[2];
|
||||
bigMod.dummy <== dummy;
|
||||
|
||||
out <== bigMod.mod;
|
||||
}
|
||||
@@ -345,10 +325,9 @@ template BigSubNoBorrow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
out[i] <== in[0][i] - in[1][i] + dummy * dummy;
|
||||
out[i] <== in[0][i] - in[1][i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,10 +337,8 @@ template BigSubNoBorrow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
template BigSub(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
component bigSubNoBorrow = BigSubNoBorrow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
bigSubNoBorrow.in <== in;
|
||||
bigSubNoBorrow.dummy <== dummy;
|
||||
|
||||
component lessThan[CHUNK_NUMBER];
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
@@ -369,11 +346,11 @@ template BigSub(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
lessThan[i].in[1] <== 2 ** CHUNK_SIZE;
|
||||
|
||||
if (i == 0){
|
||||
lessThan[i].in[0] <== bigSubNoBorrow.out[i] + 2 ** CHUNK_SIZE + dummy * dummy;
|
||||
out[i] <== bigSubNoBorrow.out[i] + (2 ** CHUNK_SIZE) * (lessThan[i].out) + dummy * dummy;
|
||||
lessThan[i].in[0] <== bigSubNoBorrow.out[i] + 2 ** CHUNK_SIZE;
|
||||
out[i] <== bigSubNoBorrow.out[i] + (2 ** CHUNK_SIZE) * (lessThan[i].out);
|
||||
} else {
|
||||
lessThan[i].in[0] <== bigSubNoBorrow.out[i] - lessThan[i - 1].out + 2 ** CHUNK_SIZE + dummy * dummy;
|
||||
out[i] <== bigSubNoBorrow.out[i] + (2 ** CHUNK_SIZE) * (lessThan[i].out) - lessThan[i - 1].out + dummy * dummy;
|
||||
lessThan[i].in[0] <== bigSubNoBorrow.out[i] - lessThan[i - 1].out + 2 ** CHUNK_SIZE;
|
||||
out[i] <== bigSubNoBorrow.out[i] + (2 ** CHUNK_SIZE) * (lessThan[i].out) - lessThan[i - 1].out;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,24 +363,21 @@ template PowerMod(CHUNK_SIZE, CHUNK_NUMBER, EXP) {
|
||||
|
||||
signal input base[CHUNK_NUMBER];
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
signal output out[CHUNK_NUMBER];
|
||||
|
||||
var exp_process[256] = exp_to_bits(EXP);
|
||||
var exp_process[256] = exp_to_bits_dl(EXP);
|
||||
|
||||
component muls[exp_process[0]];
|
||||
component resultMuls[exp_process[1] - 1];
|
||||
|
||||
for (var i = 0; i < exp_process[0]; i++){
|
||||
muls[i] = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
muls[i].dummy <== dummy;
|
||||
muls[i].in[2] <== modulus;
|
||||
}
|
||||
|
||||
for (var i = 0; i < exp_process[1] - 1; i++){
|
||||
resultMuls[i] = BigMultModP(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
resultMuls[i].dummy <== dummy;
|
||||
resultMuls[i].in[2] <== modulus;
|
||||
}
|
||||
|
||||
@@ -447,10 +421,8 @@ template BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER) {
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
var inv[200] = mod_inv(CHUNK_SIZE, CHUNK_NUMBER, in, modulus);
|
||||
var inv[200] = mod_inv_dl(CHUNK_SIZE, CHUNK_NUMBER, in, modulus);
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
out[i] <-- inv[i];
|
||||
}
|
||||
@@ -459,7 +431,6 @@ template BigModInvOptimised(CHUNK_SIZE, CHUNK_NUMBER) {
|
||||
mult.in[0] <== in;
|
||||
mult.in[1] <== out;
|
||||
mult.in[2] <== modulus;
|
||||
mult.dummy <== dummy;
|
||||
|
||||
mult.out[0] === 1;
|
||||
for (var i = 1; i < CHUNK_NUMBER; i++) {
|
||||
@@ -476,7 +447,6 @@ template BigAddNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS){
|
||||
|
||||
signal input in1[CHUNK_NUMBER_GREATER];
|
||||
signal input in2[CHUNK_NUMBER_LESS];
|
||||
signal input dummy;
|
||||
|
||||
signal output out[CHUNK_NUMBER_GREATER + 1];
|
||||
|
||||
@@ -489,7 +459,6 @@ template BigAddNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS){
|
||||
bigAdd.in[0][i] <== in1[i];
|
||||
bigAdd.in[1][i] <== 0;
|
||||
}
|
||||
bigAdd.dummy <== dummy;
|
||||
|
||||
out <== bigAdd.out;
|
||||
}
|
||||
@@ -504,7 +473,6 @@ template BigMultNoCarryNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_L
|
||||
|
||||
signal input in1[CHUNK_NUMBER_GREATER];
|
||||
signal input in2[CHUNK_NUMBER_LESS];
|
||||
signal input dummy;
|
||||
signal output out[CHUNK_NUMBER_GREATER + CHUNK_NUMBER_LESS - 1];
|
||||
|
||||
|
||||
@@ -539,7 +507,7 @@ template BigMultNoCarryNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_L
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[i - j][j];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][i];
|
||||
@@ -550,7 +518,7 @@ template BigMultNoCarryNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_L
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[i - j][j];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][CHUNK_NUMBER_LESS - 1];
|
||||
@@ -576,7 +544,6 @@ template BigMultNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS){
|
||||
|
||||
signal input in1[CHUNK_NUMBER_GREATER];
|
||||
signal input in2[CHUNK_NUMBER_LESS];
|
||||
signal input dummy;
|
||||
signal output out[CHUNK_NUMBER_GREATER + CHUNK_NUMBER_LESS];
|
||||
var isPowerOfTwo = 0;
|
||||
for (var i = 0; i < CHUNK_NUMBER_GREATER; i++){
|
||||
@@ -585,12 +552,10 @@ template BigMultNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS){
|
||||
}
|
||||
}
|
||||
if (isPowerOfTwo == 0){
|
||||
dummy * dummy === 0;
|
||||
|
||||
component bigMultNoCarry = BigMultNoCarryNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS);
|
||||
bigMultNoCarry.in1 <== in1;
|
||||
bigMultNoCarry.in2 <== in2;
|
||||
bigMultNoCarry.dummy <== dummy;
|
||||
|
||||
component num2bits[CHUNK_NUMBER_GREATER + CHUNK_NUMBER_LESS - 1];
|
||||
component bits2numOverflow[CHUNK_NUMBER_GREATER + CHUNK_NUMBER_LESS - 1];
|
||||
@@ -614,7 +579,7 @@ template BigMultNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS){
|
||||
if (i == 0){
|
||||
num2bits[i].in <== bigMultNoCarry.out[i];
|
||||
} else {
|
||||
num2bits[i].in <== bigMultNoCarry.out[i] + bits2numOverflow[i - 1].out + dummy * dummy;
|
||||
num2bits[i].in <== bigMultNoCarry.out[i] + bits2numOverflow[i - 1].out;
|
||||
}
|
||||
|
||||
bits2numOverflow[i] = Bits2Num(CHUNK_SIZE + ADDITIONAL_LEN);
|
||||
@@ -644,7 +609,6 @@ template BigMultNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS){
|
||||
bigMult.in[0][i] <== in1[i];
|
||||
bigMult.in[1][i] <== 0;
|
||||
}
|
||||
bigMult.dummy <== dummy;
|
||||
for (var i = 0; i < CHUNK_NUMBER_LESS + CHUNK_NUMBER_GREATER; i++){
|
||||
out[i] <== bigMult.out[i];
|
||||
}
|
||||
@@ -677,9 +641,8 @@ template BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_MODULUS){
|
||||
|
||||
signal input base[CHUNK_NUMBER_BASE];
|
||||
signal input modulus[CHUNK_NUMBER_MODULUS];
|
||||
signal input dummy;
|
||||
|
||||
var long_division[2][200] = long_div(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV - 1, base, modulus);
|
||||
var long_division[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV - 1, base, modulus);
|
||||
|
||||
signal output div[CHUNK_NUMBER_DIV];
|
||||
signal output mod[CHUNK_NUMBER_MODULUS];
|
||||
@@ -698,13 +661,11 @@ template BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_MODULUS){
|
||||
|
||||
multChecks.in1 <== div;
|
||||
multChecks.in2 <== modulus;
|
||||
multChecks.dummy <== dummy;
|
||||
} else {
|
||||
multChecks = BigMultNonEqual(CHUNK_SIZE, CHUNK_NUMBER_MODULUS, CHUNK_NUMBER_DIV);
|
||||
|
||||
multChecks.in2 <== div;
|
||||
multChecks.in1 <== modulus;
|
||||
multChecks.dummy <== dummy;
|
||||
}
|
||||
|
||||
component greaterThan = BigGreaterThan(CHUNK_SIZE, CHUNK_NUMBER_MODULUS);
|
||||
@@ -719,7 +680,6 @@ template BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_MODULUS){
|
||||
|
||||
bigAddCheck.in1 <== multChecks.out;
|
||||
bigAddCheck.in2 <== mod;
|
||||
bigAddCheck.dummy <== dummy;
|
||||
|
||||
component smartEqual = SmartEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE + 2);
|
||||
smartEqual.in[0] <== bigAddCheck.out;
|
||||
@@ -728,7 +688,6 @@ template BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_MODULUS){
|
||||
}
|
||||
smartEqual.in[1][CHUNK_NUMBER_BASE] <== 0;
|
||||
smartEqual.in[1][CHUNK_NUMBER_BASE + 1] <== 0;
|
||||
smartEqual.dummy <== dummy;
|
||||
|
||||
smartEqual.out === 1;
|
||||
}
|
||||
@@ -740,20 +699,16 @@ template BigMultModPNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS
|
||||
signal input in1[CHUNK_NUMBER_GREATER];
|
||||
signal input in2[CHUNK_NUMBER_LESS];
|
||||
signal input modulus[CHUNK_NUMBER_MODULUS];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[CHUNK_NUMBER_MODULUS];
|
||||
|
||||
component bigMult = BigMultNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_LESS);
|
||||
bigMult.in1 <== in1;
|
||||
bigMult.in2 <== in2;
|
||||
bigMult.dummy <== dummy;
|
||||
|
||||
component bigMod = BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_GREATER + CHUNK_NUMBER_LESS, CHUNK_NUMBER_MODULUS);
|
||||
bigMod.base <== bigMult.out;
|
||||
bigMod.modulus <== modulus;
|
||||
bigMod.dummy <== dummy;
|
||||
|
||||
out <== bigMod.mod;
|
||||
}
|
||||
@@ -801,24 +756,21 @@ template PowerModNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, EXP) {
|
||||
|
||||
signal input base[CHUNK_NUMBER];
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
signal output out[CHUNK_NUMBER];
|
||||
|
||||
var exp_process[256] = exp_to_bits(EXP);
|
||||
var exp_process[256] = exp_to_bits_dl(EXP);
|
||||
|
||||
component muls[exp_process[0]];
|
||||
component resultMuls[exp_process[1] - 1];
|
||||
|
||||
for (var i = 0; i < exp_process[0]; i++){
|
||||
muls[i] = BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
muls[i].dummy <== dummy;
|
||||
muls[i].in[2] <== modulus;
|
||||
}
|
||||
|
||||
for (var i = 0; i < exp_process[1] - 1; i++){
|
||||
resultMuls[i] = BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
resultMuls[i].dummy <== dummy;
|
||||
resultMuls[i].in[2] <== modulus;
|
||||
}
|
||||
|
||||
@@ -862,7 +814,7 @@ template PowerModNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, EXP) {
|
||||
// those are very "expensive" by constraints operations, try to reduse num of usage if these if u can
|
||||
|
||||
// in[0] < in[1]
|
||||
template BigLessThan(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
template BigLessThan_dl(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
|
||||
signal output out;
|
||||
@@ -940,7 +892,7 @@ template BigGreaterEqThan(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal output out;
|
||||
|
||||
component lessThan = BigLessThan(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
component lessThan = BigLessThan_dl(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
lessThan.in <== in;
|
||||
out <== 1 - lessThan.out;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
function isNegative(x) {
|
||||
return x > 10944121435919637611123202872628637544274182200208017171849102093287904247808 ? 1 : 0;
|
||||
}
|
||||
// @zkemail
|
||||
|
||||
function div_ceil(m, n) {
|
||||
function div_ceil_dl(m, n) {
|
||||
var ret = 0;
|
||||
if (m % n == 0) {
|
||||
ret = m \ n;
|
||||
@@ -14,7 +12,7 @@ function div_ceil(m, n) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
function log_ceil(n) {
|
||||
function log_ceil_dl(n) {
|
||||
var n_temp = n;
|
||||
for (var i = 0; i < 254; i++) {
|
||||
if (n_temp == 0) {
|
||||
@@ -25,24 +23,130 @@ function log_ceil(n) {
|
||||
return 254;
|
||||
}
|
||||
|
||||
function SplitFn(in, n, m) {
|
||||
// 1 if true, 0 if false
|
||||
function long_gt_dl(n, k, a, b) {
|
||||
for (var i = k - 1; i >= 0; i--) {
|
||||
if (a[i] > b[i]) {
|
||||
return 1;
|
||||
}
|
||||
if (a[i] < b[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a has k registers
|
||||
// b has k registers
|
||||
// a >= b
|
||||
function long_sub_dl(n, k, a, b) {
|
||||
var diff[200];
|
||||
var borrow[200];
|
||||
for (var i = 0; i < k; i++) {
|
||||
if (i == 0) {
|
||||
if (a[i] >= b[i]) {
|
||||
diff[i] = a[i] - b[i];
|
||||
borrow[i] = 0;
|
||||
} else {
|
||||
diff[i] = a[i] - b[i] + (1 << n);
|
||||
borrow[i] = 1;
|
||||
}
|
||||
} else {
|
||||
if (a[i] >= b[i] + borrow[i - 1]) {
|
||||
diff[i] = a[i] - b[i] - borrow[i - 1];
|
||||
borrow[i] = 0;
|
||||
} else {
|
||||
diff[i] = (1 << n) + a[i] - b[i] - borrow[i - 1];
|
||||
borrow[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
// a is a n-bit scalar
|
||||
// b has k registers
|
||||
function long_scalar_mult_dl(n, k, a, b) {
|
||||
var out[200];
|
||||
for (var i = 0; i < 200; i++) {
|
||||
out[i] = 0;
|
||||
}
|
||||
for (var i = 0; i < k; i++) {
|
||||
var temp = out[i] + (a * b[i]);
|
||||
out[i] = temp % (1 << n);
|
||||
out[i + 1] = out[i + 1] + temp \ (1 << n);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a has k + 1 registers
|
||||
// b has k registers
|
||||
// assumes leading digit of b is at least 2 ** (n - 1)
|
||||
// 0 <= a < (2**n) * b
|
||||
function short_div_norm_dl(n, k, a, b) {
|
||||
var qhat = (a[k] * (1 << n) + a[k - 1]) \ b[k - 1];
|
||||
if (qhat > (1 << n) - 1) {
|
||||
qhat = (1 << n) - 1;
|
||||
}
|
||||
|
||||
var mult[200] = long_scalar_mult_dl(n, k, qhat, b);
|
||||
if (long_gt_dl(n, k + 1, mult, a) == 1) {
|
||||
mult = long_sub_dl(n, k + 1, mult, b);
|
||||
if (long_gt_dl(n, k + 1, mult, a) == 1) {
|
||||
return qhat - 2;
|
||||
} else {
|
||||
return qhat - 1;
|
||||
}
|
||||
} else {
|
||||
return qhat;
|
||||
}
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a has k + 1 registers
|
||||
// b has k registers
|
||||
// assumes leading digit of b is non-zero
|
||||
// 0 <= a < (2**n) * b
|
||||
function short_div_dl(n, k, a, b) {
|
||||
var scale = (1 << n) \ (1 + b[k - 1]);
|
||||
|
||||
// k + 2 registers now
|
||||
var norm_a[200] = long_scalar_mult_dl(n, k + 1, scale, a);
|
||||
// k + 1 registers now
|
||||
var norm_b[200] = long_scalar_mult_dl(n, k, scale, b);
|
||||
|
||||
var ret;
|
||||
if (norm_b[k] != 0) {
|
||||
ret = short_div_norm_dl(n, k + 1, norm_a, norm_b);
|
||||
} else {
|
||||
ret = short_div_norm_dl(n, k, norm_a, norm_b);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// beginning of the UNAUDITED section
|
||||
|
||||
function SplitFn_dl(in, n, m) {
|
||||
return [in % (1 << n), (in \ (1 << n)) % (1 << m)];
|
||||
}
|
||||
|
||||
function SplitThreeFn(in, n, m, k) {
|
||||
function SplitThreeFn_dl(in, n, m, k) {
|
||||
return [in % (1 << n), (in \ (1 << n)) % (1 << m), (in \ (1 << n + m)) % (1 << k)];
|
||||
}
|
||||
|
||||
// in is an m bit number
|
||||
// split into ceil(m/n) n-bit registers
|
||||
function splitOverflowedRegister(m, n, in) {
|
||||
function splitOverflowedRegister_dl(m, n, in) {
|
||||
var out[200];
|
||||
|
||||
for (var i = 0; i < 200; i++) {
|
||||
out[i] = 0;
|
||||
}
|
||||
|
||||
var nRegisters = div_ceil(m, n);
|
||||
var nRegisters = div_ceil_dl(m, n);
|
||||
var running = in;
|
||||
for (var i = 0; i < nRegisters; i++) {
|
||||
out[i] = running % (1 << n);
|
||||
@@ -59,7 +163,7 @@ function splitOverflowedRegister(m, n, in) {
|
||||
// all others are positive
|
||||
// - 1 since the last register is included in the last ceil(m/n) array
|
||||
// + 1 since the carries from previous registers could push you over
|
||||
function getProperRepresentation(m, n, k, in) {
|
||||
function getProperRepresentation_dl(m, n, k, in) {
|
||||
var ceilMN = 0;
|
||||
if (m % n == 0) {
|
||||
ceilMN = m \ n;
|
||||
@@ -72,13 +176,13 @@ function getProperRepresentation(m, n, k, in) {
|
||||
for (var j = 0; j < 200; j++) {
|
||||
pieces[i][j] = 0;
|
||||
}
|
||||
if (isNegative(in[i]) == 1) {
|
||||
var negPieces[200] = splitOverflowedRegister(m, n, - 1 * in[i]);
|
||||
if (isNegative_dl(in[i]) == 1) {
|
||||
var negPieces[200] = splitOverflowedRegister_dl(m, n, - 1 * in[i]);
|
||||
for (var j = 0; j < ceilMN; j++) {
|
||||
pieces[i][j] = - 1 * negPieces[j];
|
||||
}
|
||||
} else {
|
||||
pieces[i] = splitOverflowedRegister(m, n, in[i]);
|
||||
pieces[i] = splitOverflowedRegister_dl(m, n, in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +210,7 @@ function getProperRepresentation(m, n, k, in) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isNegative(thisRegisterValue) == 1) {
|
||||
if (isNegative_dl(thisRegisterValue) == 1) {
|
||||
var thisRegisterAbs = - 1 * thisRegisterValue;
|
||||
out[registerIdx] = (1 << n) - (thisRegisterAbs % (1 << n));
|
||||
carries[registerIdx] = - 1 * (thisRegisterAbs >> n) - 1;
|
||||
@@ -119,64 +223,7 @@ function getProperRepresentation(m, n, k, in) {
|
||||
return out;
|
||||
}
|
||||
|
||||
// 1 if true, 0 if false
|
||||
function long_gt(n, k, a, b) {
|
||||
for (var i = k - 1; i >= 0; i--) {
|
||||
if (a[i] > b[i]) {
|
||||
return 1;
|
||||
}
|
||||
if (a[i] < b[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a has k registers
|
||||
// b has k registers
|
||||
// a >= b
|
||||
function long_sub(n, k, a, b) {
|
||||
var diff[200];
|
||||
var borrow[200];
|
||||
for (var i = 0; i < k; i++) {
|
||||
if (i == 0) {
|
||||
if (a[i] >= b[i]) {
|
||||
diff[i] = a[i] - b[i];
|
||||
borrow[i] = 0;
|
||||
} else {
|
||||
diff[i] = a[i] - b[i] + (1 << n);
|
||||
borrow[i] = 1;
|
||||
}
|
||||
} else {
|
||||
if (a[i] >= b[i] + borrow[i - 1]) {
|
||||
diff[i] = a[i] - b[i] - borrow[i - 1];
|
||||
borrow[i] = 0;
|
||||
} else {
|
||||
diff[i] = (1 << n) + a[i] - b[i] - borrow[i - 1];
|
||||
borrow[i] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
// a is a n-bit scalar
|
||||
// b has k registers
|
||||
function long_scalar_mult(n, k, a, b) {
|
||||
var out[200];
|
||||
for (var i = 0; i < 200; i++) {
|
||||
out[i] = 0;
|
||||
}
|
||||
for (var i = 0; i < k; i++) {
|
||||
var temp = out[i] + (a * b[i]);
|
||||
out[i] = temp % (1 << n);
|
||||
out[i + 1] = out[i + 1] + temp \ (1 << n);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
// tweaked from @zkemail implementation
|
||||
// n bits per register
|
||||
// a has k + m registers
|
||||
// b has k registers
|
||||
@@ -184,7 +231,7 @@ function long_scalar_mult(n, k, a, b) {
|
||||
// out[1] has length k -- remainder
|
||||
// implements algorithm of https://people.eecs.berkeley.edu/~fateman/282/F%20Wright%20notes/week4.pdf
|
||||
// b[k-1] must be nonzero!
|
||||
function long_div(n, k, m, a, b){
|
||||
function long_div_dl(n, k, m, a, b){
|
||||
var out[2][200];
|
||||
|
||||
var remainder[200];
|
||||
@@ -206,9 +253,9 @@ function long_div(n, k, m, a, b){
|
||||
}
|
||||
}
|
||||
|
||||
out[0][i] = short_div(n, k, dividend, b);
|
||||
out[0][i] = short_div_dl(n, k, dividend, b);
|
||||
|
||||
var mult_shift[200] = long_scalar_mult(n, k, out[0][i], b);
|
||||
var mult_shift[200] = long_scalar_mult_dl(n, k, out[0][i], b);
|
||||
var subtrahend[200];
|
||||
for (var j = 0; j < m + k; j++) {
|
||||
subtrahend[j] = 0;
|
||||
@@ -218,7 +265,7 @@ function long_div(n, k, m, a, b){
|
||||
subtrahend[i + j] = mult_shift[j];
|
||||
}
|
||||
}
|
||||
remainder = long_sub(n, m + k, remainder, subtrahend);
|
||||
remainder = long_sub_dl(n, m + k, remainder, subtrahend);
|
||||
}
|
||||
for (var i = 0; i < k; i++) {
|
||||
out[1][i] = remainder[i];
|
||||
@@ -228,57 +275,13 @@ function long_div(n, k, m, a, b){
|
||||
return out;
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a has k + 1 registers
|
||||
// b has k registers
|
||||
// assumes leading digit of b is at least 2 ** (n - 1)
|
||||
// 0 <= a < (2**n) * b
|
||||
function short_div_norm(n, k, a, b) {
|
||||
var qhat = (a[k] * (1 << n) + a[k - 1]) \ b[k - 1];
|
||||
if (qhat > (1 << n) - 1) {
|
||||
qhat = (1 << n) - 1;
|
||||
}
|
||||
|
||||
var mult[200] = long_scalar_mult(n, k, qhat, b);
|
||||
if (long_gt(n, k + 1, mult, a) == 1) {
|
||||
mult = long_sub(n, k + 1, mult, b);
|
||||
if (long_gt(n, k + 1, mult, a) == 1) {
|
||||
return qhat - 2;
|
||||
} else {
|
||||
return qhat - 1;
|
||||
}
|
||||
} else {
|
||||
return qhat;
|
||||
}
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a has k + 1 registers
|
||||
// b has k registers
|
||||
// assumes leading digit of b is non-zero
|
||||
// 0 <= a < (2**n) * b
|
||||
function short_div(n, k, a, b) {
|
||||
var scale = (1 << n) \ (1 + b[k - 1]);
|
||||
|
||||
// k + 2 registers now
|
||||
var norm_a[200] = long_scalar_mult(n, k + 1, scale, a);
|
||||
// k + 1 registers now
|
||||
var norm_b[200] = long_scalar_mult(n, k, scale, b);
|
||||
|
||||
var ret;
|
||||
if (norm_b[k] != 0) {
|
||||
ret = short_div_norm(n, k + 1, norm_a, norm_b);
|
||||
} else {
|
||||
ret = short_div_norm(n, k, norm_a, norm_b);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// n bits per register
|
||||
// a and b both have k registers
|
||||
// out[0] has length 2 * k
|
||||
// adapted from BigMulShortLong and LongToShortNoEndCarry2 witness computation
|
||||
function prod(n, k, a, b) {
|
||||
function prod_dl(n, k, a, b) {
|
||||
// first compute the intermediate values. taken from BigMulShortLong
|
||||
var prod_val[200];
|
||||
for (var i = 0; i < 2 * k - 1; i++) {
|
||||
@@ -299,20 +302,20 @@ function prod(n, k, a, b) {
|
||||
|
||||
var split[200][3];
|
||||
for (var i = 0; i < 2 * k - 1; i++) {
|
||||
split[i] = SplitThreeFn(prod_val[i], n, n, n);
|
||||
split[i] = SplitThreeFn_dl(prod_val[i], n, n, n);
|
||||
}
|
||||
|
||||
var carry[200];
|
||||
carry[0] = 0;
|
||||
out[0] = split[0][0];
|
||||
if (2 * k - 1 > 1) {
|
||||
var sumAndCarry[2] = SplitFn(split[0][1] + split[1][0], n, n);
|
||||
var sumAndCarry[2] = SplitFn_dl(split[0][1] + split[1][0], n, n);
|
||||
out[1] = sumAndCarry[0];
|
||||
carry[1] = sumAndCarry[1];
|
||||
}
|
||||
if (2 * k - 1 > 2) {
|
||||
for (var i = 2; i < 2 * k - 1; i++) {
|
||||
var sumAndCarry[2] = SplitFn(split[i][0] + split[i - 1][1] + split[i - 2][2] + carry[i - 1], n, n);
|
||||
var sumAndCarry[2] = SplitFn_dl(split[i][0] + split[i - 1][1] + split[i - 2][2] + carry[i - 1], n, n);
|
||||
out[i] = sumAndCarry[0];
|
||||
carry[i] = sumAndCarry[1];
|
||||
}
|
||||
@@ -347,18 +350,18 @@ function mod_exp(n, k, a, p, e) {
|
||||
// multiply by a if bit is 0
|
||||
if (eBits[i] == 1) {
|
||||
var temp[200];
|
||||
temp = prod(n, k, out, a);
|
||||
temp = prod_dl(n, k, out, a);
|
||||
var temp2[2][200];
|
||||
temp2 = long_div(n, k, k, temp, p);
|
||||
temp2 = long_div_dl(n, k, k, temp, p);
|
||||
out = temp2[1];
|
||||
}
|
||||
|
||||
// square, unless we're at the end
|
||||
if (i > 0) {
|
||||
var temp[200];
|
||||
temp = prod(n, k, out, out);
|
||||
temp = prod_dl(n, k, out, out);
|
||||
var temp2[2][200];
|
||||
temp2 = long_div(n, k, k, temp, p);
|
||||
temp2 = long_div_dl(n, k, k, temp, p);
|
||||
out = temp2[1];
|
||||
}
|
||||
|
||||
@@ -373,7 +376,7 @@ function mod_exp(n, k, a, p, e) {
|
||||
// p is a prime
|
||||
// if a == 0 mod p, returns 0
|
||||
// else computes inv = a^(p-2) mod p
|
||||
function mod_inv(n, k, a, p) {
|
||||
function mod_inv_dl(n, k, a, p) {
|
||||
var isZero = 1;
|
||||
for (var i = 0; i < k; i++) {
|
||||
if (a[i] != 0) {
|
||||
@@ -404,53 +407,53 @@ function mod_inv(n, k, a, p) {
|
||||
two[0] = 2;
|
||||
|
||||
var pMinusTwo[200];
|
||||
pMinusTwo = long_sub(n, k, pCopy, two);
|
||||
pMinusTwo = long_sub_dl(n, k, pCopy, two);
|
||||
var out[200];
|
||||
out = mod_exp(n, k, a, pCopy, pMinusTwo);
|
||||
out = mod_exp_dl(n, k, a, pCopy, pMinusTwo);
|
||||
return out;
|
||||
}
|
||||
|
||||
// a, b and out are all n bits k registers
|
||||
function long_sub_mod_p(n, k, a, b, p){
|
||||
var gt = long_gt(n, k, a, b);
|
||||
function long_sub_mod_p_dl(n, k, a, b, p){
|
||||
var gt = long_gt_dl(n, k, a, b);
|
||||
var tmp[200];
|
||||
if (gt){
|
||||
tmp = long_sub(n, k, a, b);
|
||||
tmp = long_sub_dl(n, k, a, b);
|
||||
}
|
||||
else {
|
||||
tmp = long_sub(n, k, b, a);
|
||||
tmp = long_sub_dl(n, k, b, a);
|
||||
}
|
||||
var out[2][200];
|
||||
for (var i = k; i < 2 * k; i++){
|
||||
tmp[i] = 0;
|
||||
}
|
||||
out = long_div(n, k, k, tmp, p);
|
||||
out = long_div_dl(n, k, k, tmp, p);
|
||||
if (gt == 0){
|
||||
tmp = long_sub(n, k, p, out[1]);
|
||||
tmp = long_sub_dl(n, k, p, out[1]);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// a, b, p and out are all n bits k registers
|
||||
function prod_mod_p(n, k, a, b, p){
|
||||
function prod_mod_p_dl(n, k, a, b, p){
|
||||
var tmp[200];
|
||||
var result[2][200];
|
||||
tmp = prod(n, k, a, b);
|
||||
result = long_div(n, k, k, tmp, p);
|
||||
tmp = prod_dl(n, k, a, b);
|
||||
result = long_div_dl(n, k, k, tmp, p);
|
||||
return result[1];
|
||||
}
|
||||
|
||||
function long_add_mod(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) {
|
||||
var sum[200] = long_add(CHUNK_SIZE,CHUNK_NUMBER,A,B);
|
||||
var temp[2][200] = long_div2(CHUNK_SIZE,CHUNK_NUMBER,1,sum,P);
|
||||
function long_add_mod_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) {
|
||||
var sum[200] = long_add_dl(CHUNK_SIZE,CHUNK_NUMBER,A,B);
|
||||
var temp[2][200] = long_div2_dl(CHUNK_SIZE,CHUNK_NUMBER,1,sum,P);
|
||||
return temp[1];
|
||||
}
|
||||
|
||||
function long_add(CHUNK_SIZE, CHUNK_NUMBER, A, B){
|
||||
function long_add_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B){
|
||||
var carry = 0;
|
||||
var sum[200];
|
||||
for(var i=0; i<CHUNK_NUMBER; i++){
|
||||
var sumAndCarry[2] = SplitFn(A[i] + B[i] + carry, CHUNK_SIZE, CHUNK_SIZE);
|
||||
var sumAndCarry[2] = SplitFn_dl(A[i] + B[i] + carry, CHUNK_SIZE, CHUNK_SIZE);
|
||||
sum[i] = sumAndCarry[0];
|
||||
carry = sumAndCarry[1];
|
||||
}
|
||||
@@ -459,21 +462,21 @@ function long_add(CHUNK_SIZE, CHUNK_NUMBER, A, B){
|
||||
}
|
||||
|
||||
|
||||
function long_sub_mod(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) {
|
||||
if(long_gt(CHUNK_SIZE, CHUNK_NUMBER, B, A) == 1){
|
||||
return long_add(CHUNK_SIZE, CHUNK_NUMBER, A, long_sub(CHUNK_SIZE,CHUNK_NUMBER,P,B));
|
||||
function long_sub_mod_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) {
|
||||
if(long_gt_dl(CHUNK_SIZE, CHUNK_NUMBER, B, A) == 1){
|
||||
return long_add_dl(CHUNK_SIZE, CHUNK_NUMBER, A, long_sub_dl(CHUNK_SIZE,CHUNK_NUMBER,P,B));
|
||||
}else{
|
||||
return long_sub(CHUNK_SIZE, CHUNK_NUMBER, A, B);
|
||||
return long_sub_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B);
|
||||
}
|
||||
}
|
||||
|
||||
function prod_mod(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) {
|
||||
var prod[200] = prod(CHUNK_SIZE,CHUNK_NUMBER,A,B);
|
||||
var temp[2][200] = long_div(CHUNK_SIZE,CHUNK_NUMBER,CHUNK_NUMBER, prod,P);
|
||||
function prod_mod_dl(CHUNK_SIZE, CHUNK_NUMBER, A, B, P) {
|
||||
var prod[200] = prod_dl(CHUNK_SIZE,CHUNK_NUMBER,A,B);
|
||||
var temp[2][200] = long_div_dl(CHUNK_SIZE,CHUNK_NUMBER,CHUNK_NUMBER, prod,P);
|
||||
return temp[1];
|
||||
}
|
||||
|
||||
function long_div2(CHUNK_SIZE, CHUNK_NUMBER, M, A, B){
|
||||
function long_div2_dl(CHUNK_SIZE, CHUNK_NUMBER, M, A, B){
|
||||
var out[2][200];
|
||||
// assume CHUNK_NUMBER+M < 200
|
||||
var remainder[200];
|
||||
@@ -493,8 +496,8 @@ function long_div2(CHUNK_SIZE, CHUNK_NUMBER, M, A, B){
|
||||
dividend[j] = remainder[j + i];
|
||||
}
|
||||
}
|
||||
out[0][i] = short_div(CHUNK_SIZE, CHUNK_NUMBER, dividend, B);
|
||||
var MULT_SHIFT[200] = long_scalar_mult(CHUNK_SIZE, CHUNK_NUMBER, out[0][i], B);
|
||||
out[0][i] = short_div_dl(CHUNK_SIZE, CHUNK_NUMBER, dividend, B);
|
||||
var MULT_SHIFT[200] = long_scalar_mult_dl(CHUNK_SIZE, CHUNK_NUMBER, out[0][i], B);
|
||||
var subtrahend[200];
|
||||
for (var j = 0; j < M + CHUNK_NUMBER; j++) {
|
||||
subtrahend[j] = 0;
|
||||
@@ -504,7 +507,7 @@ function long_div2(CHUNK_SIZE, CHUNK_NUMBER, M, A, B){
|
||||
subtrahend[i + j] = MULT_SHIFT[j];
|
||||
}
|
||||
}
|
||||
remainder = long_sub(CHUNK_SIZE, M + CHUNK_NUMBER, remainder, subtrahend);
|
||||
remainder = long_sub_dl(CHUNK_SIZE, M + CHUNK_NUMBER, remainder, subtrahend);
|
||||
}
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
out[1][i] = remainder[i];
|
||||
@@ -513,7 +516,7 @@ function long_div2(CHUNK_SIZE, CHUNK_NUMBER, M, A, B){
|
||||
return out;
|
||||
}
|
||||
|
||||
function reduce_overflow(n, k, m, N){
|
||||
function reduce_overflow_dl(n, k, m, N){
|
||||
var M[200];
|
||||
var overflow = 0;
|
||||
for (var i = 0; i < k; i++){
|
||||
@@ -533,7 +536,7 @@ function reduce_overflow(n, k, m, N){
|
||||
return M;
|
||||
}
|
||||
|
||||
function exp_to_bits(exp){
|
||||
function exp_to_bits_dl(exp){
|
||||
var mul_num = 0;
|
||||
var result_mul_num = 0;
|
||||
var indexes[256];
|
||||
@@ -558,4 +561,8 @@ function exp_to_bits(exp){
|
||||
|
||||
return indexes;
|
||||
|
||||
}
|
||||
|
||||
function isNegative_dl(x) {
|
||||
return x > 10944121435919637611123202872628637544274182200208017171849102093287904247808 ? 1 : 0;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../bitify/comparators.circom";
|
||||
include "../bitify/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "./bigInt.circom";
|
||||
include "./bigIntFunc.circom";
|
||||
include "../int/arithmetic.circom";
|
||||
@@ -27,12 +27,10 @@ template BigAddOverflow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
out[i] <== in[0][i] + in[1][i] + dummy * dummy;
|
||||
out[i] <== in[0][i] + in[1][i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,13 +40,12 @@ template BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_L
|
||||
signal input in1[CHUNK_NUMBER_GREATER];
|
||||
signal input in2[CHUNK_NUMBER_LESS];
|
||||
signal output out[CHUNK_NUMBER_GREATER];
|
||||
signal input dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER_LESS; i++){
|
||||
out[i] <== in1[i] + in2[i] + dummy * dummy;
|
||||
out[i] <== in1[i] + in2[i];
|
||||
}
|
||||
for (var i = CHUNK_NUMBER_LESS; i < CHUNK_NUMBER_GREATER; i++){
|
||||
out[i] <== in1[i] + dummy * dummy;
|
||||
out[i] <== in1[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +57,6 @@ template BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
assert(CHUNK_SIZE <= 126);
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
signal output out[CHUNK_NUMBER * 2 - 1];
|
||||
|
||||
signal tmpMults[CHUNK_NUMBER][CHUNK_NUMBER];
|
||||
@@ -90,7 +86,7 @@ template BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[i - j][j];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][i];
|
||||
@@ -100,7 +96,7 @@ template BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[CHUNK_NUMBER - 1 - j][i + j - CHUNK_NUMBER + 1];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[CHUNK_NUMBER - 1 - j][i + j - CHUNK_NUMBER + 1] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[CHUNK_NUMBER - 1 - j][i + j - CHUNK_NUMBER + 1] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][2 * CHUNK_NUMBER - 2 - i];
|
||||
@@ -117,12 +113,10 @@ template BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
assert(CHUNK_SIZE <= 126);
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
signal output out[CHUNK_NUMBER * 2 - 1];
|
||||
|
||||
component karatsuba = KaratsubaNoCarry(CHUNK_NUMBER);
|
||||
karatsuba.in <== in;
|
||||
karatsuba.dummy <== dummy;
|
||||
for (var i = 0; i < CHUNK_NUMBER * 2 - 1; i++){
|
||||
out[i] <== karatsuba.out[i];
|
||||
}
|
||||
@@ -137,7 +131,6 @@ template BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_
|
||||
|
||||
signal input in1[CHUNK_NUMBER_GREATER];
|
||||
signal input in2[CHUNK_NUMBER_LESS];
|
||||
signal input dummy;
|
||||
signal output out[CHUNK_NUMBER_GREATER + CHUNK_NUMBER_LESS - 1];
|
||||
|
||||
|
||||
@@ -172,7 +165,7 @@ template BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[i - j][j];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][i];
|
||||
@@ -183,7 +176,7 @@ template BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER_GREATER, CHUNK_NUMBER_
|
||||
if (j == 0){
|
||||
tmpResult[i][j] <== tmpMults[i - j][j];
|
||||
} else {
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1] + dummy * dummy;
|
||||
tmpResult[i][j] <== tmpMults[i - j][j] + tmpResult[i][j - 1];
|
||||
}
|
||||
}
|
||||
out[i] <== tmpResult[i][CHUNK_NUMBER_LESS - 1];
|
||||
@@ -209,19 +202,16 @@ template BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_MODULUS, OVE
|
||||
|
||||
signal input base[CHUNK_NUMBER_BASE];
|
||||
signal input modulus[CHUNK_NUMBER_MODULUS];
|
||||
signal input dummy;
|
||||
|
||||
signal output mod[CHUNK_NUMBER_MODULUS];
|
||||
signal output div[CHUNK_NUMBER_BASE + OVERFLOW_SHIFT - CHUNK_NUMBER_MODULUS + 1];
|
||||
|
||||
component reduce = RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_BASE + OVERFLOW_SHIFT);
|
||||
reduce.in <== base;
|
||||
reduce.dummy <== dummy;
|
||||
|
||||
component bigMod = BigModNonEqual(CHUNK_SIZE, CHUNK_NUMBER_BASE + OVERFLOW_SHIFT, CHUNK_NUMBER_MODULUS);
|
||||
bigMod.base <== reduce.out;
|
||||
bigMod.modulus <== modulus;
|
||||
bigMod.dummy <== dummy;
|
||||
|
||||
bigMod.mod ==> mod;
|
||||
bigMod.div ==> div;
|
||||
@@ -235,19 +225,16 @@ template BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER) {
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal output out[CHUNK_NUMBER];
|
||||
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
component reduce = RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER_BASE + 1);
|
||||
reduce.in <== in;
|
||||
reduce.dummy <== dummy;
|
||||
|
||||
var div_res[2][200] = long_div(CHUNK_SIZE, CHUNK_NUMBER, (CHUNK_NUMBER_BASE + 1 - CHUNK_NUMBER), reduce.out, modulus);
|
||||
var div_res[2][200] = long_div_dl(CHUNK_SIZE, CHUNK_NUMBER, (CHUNK_NUMBER_BASE + 1 - CHUNK_NUMBER), reduce.out, modulus);
|
||||
var mod[CHUNK_NUMBER];
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
mod[i] = div_res[1][i];
|
||||
}
|
||||
var inv[200] = mod_inv(CHUNK_SIZE, CHUNK_NUMBER, mod, modulus);
|
||||
var inv[200] = mod_inv_dl(CHUNK_SIZE, CHUNK_NUMBER, mod, modulus);
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
out[i] <-- inv[i];
|
||||
@@ -257,7 +244,6 @@ template BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER_BASE, CHUNK_NUMBER) {
|
||||
mult.in1 <== reduce.out;
|
||||
mult.in2 <== out;
|
||||
mult.modulus <== modulus;
|
||||
mult.dummy <== dummy;
|
||||
|
||||
mult.out[0] === 1;
|
||||
for (var i = 1; i < CHUNK_NUMBER; i++) {
|
||||
@@ -283,8 +269,6 @@ template RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_OLD, CHUNK_NUMBER_NEW){
|
||||
assert(CHUNK_SIZE <= 126);
|
||||
assert(CHUNK_NUMBER_OLD <= CHUNK_NUMBER_NEW);
|
||||
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal input in[CHUNK_NUMBER_OLD];
|
||||
signal output out[CHUNK_NUMBER_NEW];
|
||||
|
||||
@@ -300,7 +284,7 @@ template RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_OLD, CHUNK_NUMBER_NEW){
|
||||
out[i] <== bits2Num[i].out;
|
||||
} else {
|
||||
getLastNBits[i] = GetLastNBits(CHUNK_SIZE);
|
||||
getLastNBits[i].in <== in[i] + getLastNBits[i - 1].div + dummy * dummy;
|
||||
getLastNBits[i].in <== in[i] + getLastNBits[i - 1].div;
|
||||
bits2Num[i] = Bits2Num(CHUNK_SIZE);
|
||||
bits2Num[i].in <== getLastNBits[i].out;
|
||||
out[i] <== bits2Num[i].out;
|
||||
@@ -324,13 +308,13 @@ template RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_OLD, CHUNK_NUMBER_NEW){
|
||||
out[i] <== bits2Num[i].out;
|
||||
} else {
|
||||
getLastNBits[i] = GetLastNBits(CHUNK_SIZE);
|
||||
getLastNBits[i].in <== in[i] + getLastNBits[i - 1].div + dummy * dummy;
|
||||
getLastNBits[i].in <== in[i] + getLastNBits[i - 1].div;
|
||||
bits2Num[i] = Bits2Num(CHUNK_SIZE);
|
||||
bits2Num[i].in <== getLastNBits[i].out;
|
||||
out[i] <== bits2Num[i].out;
|
||||
}
|
||||
}
|
||||
out[CHUNK_NUMBER_NEW - 1] <== getLastNBits[CHUNK_NUMBER_NEW - 2].div + in[CHUNK_NUMBER_NEW - 1] + dummy * dummy;
|
||||
out[CHUNK_NUMBER_NEW - 1] <== getLastNBits[CHUNK_NUMBER_NEW - 2].div + in[CHUNK_NUMBER_NEW - 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,20 +324,18 @@ template BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
signal input in1[CHUNK_NUMBER];
|
||||
signal input in2[CHUNK_NUMBER];
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[CHUNK_NUMBER];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
if (i == 0){
|
||||
out[i] <== 2 ** CHUNK_SIZE + modulus[i] + in1[i] - in2[i] + dummy * dummy;
|
||||
out[i] <== 2 ** CHUNK_SIZE + modulus[i] + in1[i] - in2[i];
|
||||
} else {
|
||||
if (i == CHUNK_NUMBER - 1){
|
||||
out[i] <== modulus[i] + in1[i] - in2[i] - 1 + dummy * dummy;
|
||||
out[i] <== modulus[i] + in1[i] - in2[i] - 1;
|
||||
} else {
|
||||
out[i] <== 2 ** CHUNK_SIZE + modulus[i] + in1[i] - in2[i] - 1 + dummy * dummy;
|
||||
out[i] <== 2 ** CHUNK_SIZE + modulus[i] + in1[i] - in2[i] - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -391,13 +373,10 @@ template ForceEqual(CHUNK_NUMBER){
|
||||
template ReducedEqual(CHUNK_SIZE, CHUNK_NUMBER_OLD, CHUNK_NUMBER_NEW){
|
||||
signal input in1[CHUNK_NUMBER_NEW];
|
||||
signal input in2[CHUNK_NUMBER_OLD];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out;
|
||||
|
||||
component reduce = RemoveOverflow(CHUNK_SIZE, CHUNK_NUMBER_OLD, CHUNK_NUMBER_NEW);
|
||||
reduce.in <== in2;
|
||||
reduce.dummy <== dummy;
|
||||
|
||||
component forceEqual = ForceEqual(CHUNK_NUMBER_NEW);
|
||||
forceEqual.in[0] <== in1;
|
||||
@@ -415,13 +394,9 @@ template ReducedEqual(CHUNK_SIZE, CHUNK_NUMBER_OLD, CHUNK_NUMBER_NEW){
|
||||
template SmartEqual(CHUNK_SIZE, CHUNK_NUMBER){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out;
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
component isEqual = IsEqual();
|
||||
component sumLeft = GetSumOfNElements(CHUNK_NUMBER);
|
||||
sumLeft.dummy <== dummy;
|
||||
component sumRight = GetSumOfNElements(CHUNK_NUMBER);
|
||||
sumRight.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
sumLeft.in[i] <== 2 ** (i * CHUNK_SIZE) * in[0][i];
|
||||
|
||||
@@ -7,7 +7,6 @@ pragma circom 2.1.6;
|
||||
template KaratsubaNoCarry(CHUNK_NUMBER) {
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[2 * CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
if (CHUNK_NUMBER == 1) {
|
||||
out[0] <== in[0][0] * in[1][0];
|
||||
@@ -15,9 +14,6 @@ template KaratsubaNoCarry(CHUNK_NUMBER) {
|
||||
component karatsubaA1B1 = KaratsubaNoCarry(CHUNK_NUMBER / 2);
|
||||
component karatsubaA2B2 = KaratsubaNoCarry(CHUNK_NUMBER / 2);
|
||||
component karatsubaA1A2B1B2 = KaratsubaNoCarry(CHUNK_NUMBER / 2);
|
||||
karatsubaA2B2.dummy <== dummy;
|
||||
karatsubaA1B1.dummy <== dummy;
|
||||
karatsubaA1A2B1B2.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER / 2; i++) {
|
||||
karatsubaA1B1.in[0][i] <== in[0][i];
|
||||
@@ -34,18 +30,18 @@ template KaratsubaNoCarry(CHUNK_NUMBER) {
|
||||
out[i] <== karatsubaA1B1.out[i]
|
||||
+ karatsubaA1A2B1B2.out[i - CHUNK_NUMBER / 2]
|
||||
- karatsubaA1B1.out[i - CHUNK_NUMBER / 2]
|
||||
- karatsubaA2B2.out[i - CHUNK_NUMBER / 2] + dummy * dummy;
|
||||
- karatsubaA2B2.out[i - CHUNK_NUMBER / 2];
|
||||
} else {
|
||||
out[i] <== karatsubaA1B1.out[i] + dummy * dummy;
|
||||
out[i] <== karatsubaA1B1.out[i];
|
||||
}
|
||||
} else {
|
||||
if (CHUNK_NUMBER / 2 <= i && i < 3 * (CHUNK_NUMBER / 2)) {
|
||||
out[i] <== karatsubaA2B2.out[i - CHUNK_NUMBER]
|
||||
+ karatsubaA1A2B1B2.out[i - CHUNK_NUMBER / 2]
|
||||
- karatsubaA1B1.out[i - CHUNK_NUMBER / 2]
|
||||
- karatsubaA2B2.out[i - CHUNK_NUMBER / 2] + dummy * dummy;
|
||||
- karatsubaA2B2.out[i - CHUNK_NUMBER / 2];
|
||||
} else {
|
||||
out[i] <== karatsubaA2B2.out[i - CHUNK_NUMBER] + dummy * dummy;
|
||||
out[i] <== karatsubaA2B2.out[i - CHUNK_NUMBER];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
// Here are templates for all bit gates for any 1 or 2 inputs
|
||||
// for 1-input gates interface is input in and output out
|
||||
// for 2-input gates interface is input in[2] and output out
|
||||
// 3-input gates may be added later
|
||||
|
||||
|
||||
//One input gates
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// a
|
||||
// 0 -> 0
|
||||
// 1 -> 1
|
||||
template BUFFER(){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
out <== in;
|
||||
}
|
||||
|
||||
// !a
|
||||
// !0 = 1
|
||||
// !1 = 0
|
||||
template NOT(){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//Two input gates
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// a ∧ b
|
||||
// 0 ∧ 0 = 0
|
||||
// 1 ∧ 0 = 0
|
||||
// 0 ∧ 1 = 0
|
||||
// 1 ∧ 1 = 1
|
||||
template AND(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[0] * in[1];
|
||||
}
|
||||
|
||||
// a ∨ b
|
||||
// 0 ∨ 0 = 0
|
||||
// 1 ∨ 0 = 1
|
||||
// 0 ∨ 1 = 1
|
||||
// 1 ∨ 1 = 1
|
||||
template OR(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[0] + in[1] - in[0] * in[1];
|
||||
}
|
||||
|
||||
// !(a ∧ b)
|
||||
// !(0 ∧ 0) = 1
|
||||
// !(1 ∧ 0) = 1
|
||||
// !(0 ∧ 1) = 1
|
||||
// !(1 ∧ 1) = 0
|
||||
template NAND(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in[0] * in[1];
|
||||
}
|
||||
|
||||
// !(a ∨ b)
|
||||
// !(0 ∨ 0) = 1
|
||||
// !(1 ∨ 0) = 0
|
||||
// !(0 ∨ 1) = 0
|
||||
// !(1 ∨ 1) = 0
|
||||
template NOR(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in[0] + in[1] + in[0] * in[1];
|
||||
}
|
||||
|
||||
// A ⊕ B
|
||||
// 0 ⊕ 0 = 0
|
||||
// 1 ⊕ 0 = 1
|
||||
// 0 ⊕ 1 = 1
|
||||
// 1 ⊕ 1 = 0
|
||||
template XOR(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[0] + in[1] - 2 * in[0] * in[1];
|
||||
}
|
||||
|
||||
// !(A ⊕ B)
|
||||
// !(0 ⊕ 0) = 1
|
||||
// !(1 ⊕ 0) = 0
|
||||
// !(0 ⊕ 1) = 0
|
||||
// !(1 ⊕ 1) = 1
|
||||
template XNOR(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in[0] - in[1] + 2 * in[0] * in[1];
|
||||
}
|
||||
|
||||
// A → B
|
||||
// 0 → 0 = 1
|
||||
// 1 → 0 = 1
|
||||
// 0 → 1 = 0
|
||||
// 1 → 1 = 1
|
||||
template IMPLY(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in[0] + in[1] - (1 - in[0]) * in[1];
|
||||
}
|
||||
|
||||
// !(A → B)
|
||||
// !(0 → 0) = 0
|
||||
// !(1 → 0) = 0
|
||||
// !(0 → 1) = 1
|
||||
// !(1 → 1) = 0
|
||||
template NIMPLY(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[0] - in[1] + (1 - in[0]) * in[1];
|
||||
}
|
||||
|
||||
// A
|
||||
// 0 0 -> 0
|
||||
// 1 0 -> 1
|
||||
// 0 1 -> 0
|
||||
// 1 1 -> 1
|
||||
template A(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[0];
|
||||
}
|
||||
|
||||
// !A
|
||||
// 0 0 -> 1
|
||||
// 1 0 -> 0
|
||||
// 0 1 -> 1
|
||||
// 1 1 -> 0
|
||||
template NOTA(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in[0];
|
||||
}
|
||||
|
||||
// B
|
||||
// 0 0 -> 0
|
||||
// 1 0 -> 0
|
||||
// 0 1 -> 1
|
||||
// 1 1 -> 1
|
||||
template B(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[1];
|
||||
}
|
||||
|
||||
// !B
|
||||
// 0 0 -> 1
|
||||
// 1 0 -> 1
|
||||
// 0 1 -> 0
|
||||
// 1 1 -> 0
|
||||
template NOTB(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 - in[1];
|
||||
}
|
||||
|
||||
|
||||
// true
|
||||
// 0 0 -> 1
|
||||
// 1 0 -> 1
|
||||
// 0 1 -> 1
|
||||
// 1 1 -> 1
|
||||
template TRUE(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1;
|
||||
}
|
||||
|
||||
// true
|
||||
// 0 0 -> 0
|
||||
// 1 0 -> 0
|
||||
// 0 1 -> 0
|
||||
// 1 1 -> 0
|
||||
template FALSE(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 0;
|
||||
}
|
||||
|
||||
// B → A
|
||||
// 0 0 -> 0
|
||||
// 1 0 -> 1
|
||||
// 0 1 -> 0
|
||||
// 1 1 -> 0
|
||||
template INVIMPLY(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== 1 + in[0] - in[1] - in[0] * (1 - in[1]);
|
||||
}
|
||||
|
||||
// !(B → A)
|
||||
// 0 0 -> 1
|
||||
// 1 0 -> 0
|
||||
// 0 1 -> 1
|
||||
// 1 1 -> 1
|
||||
template NINVNIMPLY(){
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
out <== in[1] - in[0] + in[0] * (1 - in[1]);
|
||||
}
|
||||
|
||||
// Xor for n pairs
|
||||
template Xor2(n) {
|
||||
signal input in1[n];
|
||||
signal input in2[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var k = 0; k < n; k++) {
|
||||
out[k] <== in1[k] + in2[k] - 2 * in1[k] * in2[k];
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//Three input gates (not all cases!!!)
|
||||
//------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1,50 +0,0 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
template Num2Bits(n) {
|
||||
signal input in;
|
||||
signal output out[n];
|
||||
var lc1=0;
|
||||
|
||||
var e2=1;
|
||||
for (var i = 0; i<n; i++) {
|
||||
out[i] <-- (in >> i) & 1;
|
||||
out[i] * (out[i] -1 ) === 0;
|
||||
lc1 += out[i] * e2;
|
||||
e2 = e2+e2;
|
||||
}
|
||||
|
||||
lc1 === in;
|
||||
}
|
||||
|
||||
template Bits2Num(n) {
|
||||
signal input in[n];
|
||||
signal output out;
|
||||
var lc1=0;
|
||||
|
||||
var e2 = 1;
|
||||
for (var i = 0; i<n; i++) {
|
||||
lc1 += in[i] * e2;
|
||||
e2 = e2 + e2;
|
||||
}
|
||||
|
||||
lc1 ==> out;
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
|
||||
/*
|
||||
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/>.
|
||||
*/
|
||||
|
||||
include "bitify.circom";
|
||||
|
||||
template IsZero() {
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal inv;
|
||||
|
||||
inv <-- in!=0 ? 1/in : 0;
|
||||
|
||||
out <== -in*inv +1;
|
||||
in*out === 0;
|
||||
}
|
||||
|
||||
|
||||
template IsEqual() {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component isz = IsZero();
|
||||
|
||||
in[1] - in[0] ==> isz.in;
|
||||
|
||||
isz.out ==> out;
|
||||
}
|
||||
|
||||
template ForceEqualIfEnabled() {
|
||||
signal input enabled;
|
||||
signal input in[2];
|
||||
|
||||
component isz = IsZero();
|
||||
|
||||
in[1] - in[0] ==> isz.in;
|
||||
|
||||
(1 - isz.out)*enabled === 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template LessThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component num2Bits0;
|
||||
component num2Bits1;
|
||||
|
||||
component adder;
|
||||
|
||||
adder = BinSum(n, 2);
|
||||
|
||||
num2Bits0 = Num2Bits(n);
|
||||
num2Bits1 = Num2BitsNeg(n);
|
||||
|
||||
in[0] ==> num2Bits0.in;
|
||||
in[1] ==> num2Bits1.in;
|
||||
|
||||
var i;
|
||||
for (i=0;i<n;i++) {
|
||||
num2Bits0.out[i] ==> adder.in[0][i];
|
||||
num2Bits1.out[i] ==> adder.in[1][i];
|
||||
}
|
||||
|
||||
adder.out[n-1] ==> out;
|
||||
}
|
||||
*/
|
||||
|
||||
template LessThan(n) {
|
||||
assert(n <= 252);
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template LessEqThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[0];
|
||||
lt.in[1] <== in[1]+1;
|
||||
lt.out ==> out;
|
||||
}
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template GreaterThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[1];
|
||||
lt.in[1] <== in[0];
|
||||
lt.out ==> out;
|
||||
}
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template GreaterEqThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[1];
|
||||
lt.in[1] <== in[0]+1;
|
||||
lt.out ==> out;
|
||||
}
|
||||
|
||||
15
circuits/circuits/utils/circomlib/bitify/gates.circom
Normal file
15
circuits/circuits/utils/circomlib/bitify/gates.circom
Normal file
@@ -0,0 +1,15 @@
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "circomlib/circuits/gates.circom";
|
||||
|
||||
|
||||
// Xor for n pairs
|
||||
template Xor2(n) {
|
||||
signal input in1[n];
|
||||
signal input in2[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var k = 0; k < n; k++) {
|
||||
out[k] <== in1[k] + in2[k] - 2 * in1[k] * in2[k];
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,19 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "./bitify.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// calculate bin sum of NUM numbers each LEN BITS
|
||||
// out is LEN + NUM - 1 LEN bit number
|
||||
|
||||
template BinSum(NUM, LEN){
|
||||
template BinSum_sha1(NUM, LEN){
|
||||
assert (LEN + NUM - 1 <= 253);
|
||||
var OUT_LEN = LEN + NUM - 1;
|
||||
signal input in[NUM][LEN];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[OUT_LEN];
|
||||
|
||||
component bits2Num[NUM];
|
||||
component sumN = GetSumOfNElements(NUM);
|
||||
sumN.dummy <== dummy;
|
||||
for (var i = 0; i < NUM; i++) {
|
||||
bits2Num[i] = Bits2Num(LEN);
|
||||
bits2Num[i].in <== in[i];
|
||||
|
||||
@@ -10,8 +10,8 @@ include "./powers/brainpoolP512r1pows.circom";
|
||||
include "./powers/p224pows.circom";
|
||||
include "./powers/p256pows.circom";
|
||||
include "./powers/p384pows.circom";
|
||||
include "../bitify/bitify.circom";
|
||||
include "../bitify/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../int/arithmetic.circom";
|
||||
include "./get.circom";
|
||||
|
||||
@@ -54,15 +54,12 @@ template TangentCheck(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
|
||||
signal input in1[2][CHUNK_NUMBER];
|
||||
signal input in2[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
component mult = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== in1[0];
|
||||
mult.in[1] <== in1[0];
|
||||
mult.dummy <== dummy;
|
||||
|
||||
component scalarMult = ScalarMultOverflow(CHUNK_NUMBER * 2 - 1);
|
||||
scalarMult.scalar <== 3;
|
||||
@@ -71,7 +68,6 @@ template TangentCheck(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component add = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add.in1 <== scalarMult.out;
|
||||
add.in2 <== A;
|
||||
add.dummy <== dummy;
|
||||
|
||||
component scalarMult2 = ScalarMultOverflow(CHUNK_NUMBER);
|
||||
scalarMult2.in <== in1[1];
|
||||
@@ -80,54 +76,44 @@ template TangentCheck(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component modInv = BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
modInv.in <== scalarMult2.out;
|
||||
modInv.modulus <== P;
|
||||
modInv.dummy <== dummy;
|
||||
|
||||
component mul2 = BigMultNonEqualOverflow(CHUNK_SIZE, 2 * CHUNK_NUMBER - 1, CHUNK_NUMBER);
|
||||
mul2.in1 <== add.out;
|
||||
mul2.in2 <== modInv.out;
|
||||
mul2.dummy <== dummy;
|
||||
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod.base <== mul2.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
component sub = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub.in1 <== in1[0];
|
||||
sub.in2 <== in2[0];
|
||||
sub.modulus <== P;
|
||||
sub.dummy <== dummy;
|
||||
|
||||
component mul3 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
mul3.in1 <== mod.mod;
|
||||
mul3.in2 <== sub.out;
|
||||
mul3.dummy <== dummy;
|
||||
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod2.base <== mul3.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
component sub2 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub2.in1 <== mod2.mod;
|
||||
sub2.in2 <== in1[1];
|
||||
sub2.modulus <== P;
|
||||
sub2.dummy <== dummy;
|
||||
|
||||
component add2 = BigAddOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
add2.in[0] <== P;
|
||||
add2.in[1] <== in2[1];
|
||||
add2.dummy <== dummy;
|
||||
|
||||
component smartEqual = SmartEqual(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
smartEqual.in[0] <== sub2.out;
|
||||
smartEqual.in[1] <== add2.out;
|
||||
smartEqual.dummy <== dummy;
|
||||
|
||||
component smartEqual2 = SmartEqual(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
smartEqual2.in[0] <== sub2.out;
|
||||
smartEqual2.in[1] <== in2[1];
|
||||
smartEqual2.dummy <== dummy;
|
||||
|
||||
smartEqual.out * smartEqual.out + smartEqual2.out === 1;
|
||||
}
|
||||
@@ -142,66 +128,54 @@ template AdditionCheck(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in1[2][CHUNK_NUMBER];
|
||||
signal input in2[2][CHUNK_NUMBER];
|
||||
signal input in3[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
component sub = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub.in1 <== in2[0];
|
||||
sub.in2 <== in1[0];
|
||||
sub.modulus <== P;
|
||||
sub.dummy <== dummy;
|
||||
|
||||
component sub2 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub2.in1 <== in2[1];
|
||||
sub2.in2 <== in1[1];
|
||||
sub2.modulus <== P;
|
||||
sub2.dummy <== dummy;
|
||||
|
||||
component sub3 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub3.in1 <== in1[0];
|
||||
sub3.in2 <== in3[0];
|
||||
sub3.modulus <== P;
|
||||
sub3.dummy <== dummy;
|
||||
|
||||
component modInv = BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
modInv.in <== sub.out;
|
||||
modInv.modulus <== P;
|
||||
modInv.dummy <== dummy;
|
||||
|
||||
component mul = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mul.in[0] <== sub2.out;
|
||||
mul.in[1] <== modInv.out;
|
||||
mul.dummy <== dummy;
|
||||
|
||||
component mul2 = BigMultNonEqualOverflow(CHUNK_SIZE, 2 * CHUNK_NUMBER - 1, CHUNK_NUMBER);
|
||||
mul2.in1 <== mul.out;
|
||||
mul2.in2 <== sub3.out;
|
||||
mul2.dummy <== dummy;
|
||||
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 2);
|
||||
mod.base <== mul2.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
component sub4 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub4.in1 <== mod.mod;
|
||||
sub4.in2 <== in1[1];
|
||||
sub4.modulus <== P;
|
||||
sub4.dummy <== dummy;
|
||||
|
||||
component add = BigAddOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
add.in[0] <== P;
|
||||
add.in[1] <== in3[1];
|
||||
add.dummy <== dummy;
|
||||
|
||||
component smartEqual = SmartEqual(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
smartEqual.in[0] <== sub4.out;
|
||||
smartEqual.in[1] <== add.out;
|
||||
smartEqual.dummy <== dummy;
|
||||
|
||||
component smartEqual2 = SmartEqual(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
smartEqual2.in[0] <== sub4.out;
|
||||
smartEqual2.in[1] <== in3[1];
|
||||
smartEqual2.dummy <== dummy;
|
||||
|
||||
smartEqual.out * smartEqual.out + smartEqual2.out === 1;
|
||||
|
||||
@@ -213,12 +187,10 @@ template AdditionCheck(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
// Computes 0 * G, 1 * G, 2 * G, ... (2 ** WINDOW_SIZE - 1) * G
|
||||
template EllipticCurvePrecomputePipinger(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZE){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
var PRECOMPUTE_NUMBER = 2 ** WINDOW_SIZE;
|
||||
|
||||
signal output out[PRECOMPUTE_NUMBER][2][CHUNK_NUMBER];
|
||||
dummy * dummy === 0;
|
||||
|
||||
for (var i = 0; i < 2; i++){
|
||||
for (var j = 0; j < CHUNK_NUMBER; j++){
|
||||
@@ -235,7 +207,6 @@ template EllipticCurvePrecomputePipinger(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WIND
|
||||
if (i % 2 == 0){
|
||||
doublers[i \ 2 - 1] = EllipticCurveDouble(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
doublers[i \ 2 - 1].in <== out[i \ 2];
|
||||
doublers[i \ 2 - 1].dummy <== dummy;
|
||||
doublers[i \ 2 - 1].out ==> out[i];
|
||||
|
||||
}
|
||||
@@ -243,7 +214,6 @@ template EllipticCurvePrecomputePipinger(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WIND
|
||||
adders[i \ 2 - 1] = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i \ 2 - 1].in1 <== out[1];
|
||||
adders[i \ 2 - 1].in2 <== out[i - 1];
|
||||
adders[i \ 2 - 1].dummy <== dummy;
|
||||
adders[i \ 2 - 1].out ==> out[i];
|
||||
}
|
||||
}
|
||||
@@ -260,48 +230,38 @@ template PointOnCurveOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert(CHUNK_SIZE == 64);
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
component mult = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== in[0];
|
||||
mult.in[1] <== in[0];
|
||||
mult.dummy <== dummy;
|
||||
|
||||
component mult2 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
mult2.in1 <== mult.out;
|
||||
mult2.in2 <== in[0];
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
component mult3 = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult3.in[0] <== in[0];
|
||||
mult3.in[1] <== A;
|
||||
mult3.dummy <== dummy;
|
||||
|
||||
component mult4 = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult4.in[0] <== in[1];
|
||||
mult4.in[1] <== in[1];
|
||||
mult4.dummy <== dummy;
|
||||
|
||||
component add = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER * 2 - 1);
|
||||
add.in1 <== mult2.out;
|
||||
add.in2 <== mult3.out;
|
||||
add.dummy <== dummy;
|
||||
|
||||
component add2 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER);
|
||||
add2.in1 <== add.out;
|
||||
add2.in2 <== B;
|
||||
add2.dummy <== dummy;
|
||||
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod.base <== mult4.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod2.base <== add2.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
mod.mod[i] === mod2.mod[i];
|
||||
@@ -316,14 +276,11 @@ template PointOnCurveOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
template EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
// x * x
|
||||
component mult = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== in[0];
|
||||
mult.in[1] <== in[0];
|
||||
mult.dummy <== dummy;
|
||||
|
||||
// 3 * x * x
|
||||
component scalarMult = ScalarMultOverflow(CHUNK_NUMBER * 2 - 1);
|
||||
@@ -334,7 +291,6 @@ template EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component add = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add.in1 <== scalarMult.out;
|
||||
add.in2 <== A;
|
||||
add.dummy <== dummy;
|
||||
|
||||
// 2 * y
|
||||
component scalarMult2 = ScalarMultOverflow(CHUNK_NUMBER);
|
||||
@@ -345,32 +301,27 @@ template EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component modInv = BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
modInv.in <== scalarMult2.out;
|
||||
modInv.modulus <== P;
|
||||
modInv.dummy <== dummy;
|
||||
|
||||
// (3 * x * x + a) * 1 / (2 * y)
|
||||
component mult2 = BigMultNonEqualOverflow(CHUNK_SIZE, 2 * CHUNK_NUMBER - 1, CHUNK_NUMBER);
|
||||
mult2.in1 <== add.out;
|
||||
mult2.in2 <== modInv.out;
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
// ((3 * x * x + a) * 1 / (2 * y)) % p ==> λ
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod.base <== mult2.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
// λ * λ
|
||||
component mult3 = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult3.in[0] <== mod.mod;
|
||||
mult3.in[1] <== mod.mod;
|
||||
mult3.dummy <== dummy;
|
||||
|
||||
// P - x
|
||||
component sub = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub.in1 <== P;
|
||||
sub.in2 <== in[0];
|
||||
sub.modulus <== P;
|
||||
sub.dummy <== dummy;
|
||||
|
||||
// 2 * P - 2 * x
|
||||
component scalarMult3 = ScalarMultOverflow(CHUNK_NUMBER);
|
||||
@@ -381,13 +332,11 @@ template EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component add2 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add2.in1 <== mult3.out;
|
||||
add2.in2 <== scalarMult3.out;
|
||||
add2.dummy <== dummy;
|
||||
|
||||
// (λ * λ + 2 * P - 2 * x) % p ==> x3
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod2.base <== add2.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
out[0] <== mod2.mod;
|
||||
|
||||
@@ -396,32 +345,27 @@ template EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
sub2.in1 <== in[0];
|
||||
sub2.in2 <== out[0];
|
||||
sub2.modulus <== P;
|
||||
sub2.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3)
|
||||
component mult4 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
mult4.in1 <== mod.mod;
|
||||
mult4.in2 <== sub2.out;
|
||||
mult4.dummy <== dummy;
|
||||
|
||||
// P - y
|
||||
component sub3 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub3.in1 <== P;
|
||||
sub3.in2 <== in[1];
|
||||
sub3.modulus <== P;
|
||||
sub3.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3) + P - y
|
||||
component add3 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add3.in1 <== mult4.out;
|
||||
add3.in2 <== sub3.out;
|
||||
add3.dummy <== dummy;
|
||||
|
||||
// (λ * (x1 - x3) + P - y) % P ==> y3
|
||||
component mod3 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod3.base <== add3.out;
|
||||
mod3.modulus <== P;
|
||||
mod3.dummy <== dummy;
|
||||
|
||||
out[1] <== mod3.mod;
|
||||
}
|
||||
@@ -435,78 +379,65 @@ template EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in1[2][CHUNK_NUMBER];
|
||||
signal input in2[2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
// x2 - x1
|
||||
component sub = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub.in1 <== in2[0];
|
||||
sub.in2 <== in1[0];
|
||||
sub.modulus <== P;
|
||||
sub.dummy <== dummy;
|
||||
|
||||
// y2 - y1
|
||||
component sub2 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub2.in1 <== in2[1];
|
||||
sub2.in2 <== in1[1];
|
||||
sub2.modulus <== P;
|
||||
sub2.dummy <== dummy;
|
||||
|
||||
// (x2 - x1) ** -1
|
||||
component modInv = BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
modInv.in <== sub.out;
|
||||
modInv.modulus <== P;
|
||||
modInv.dummy <== dummy;
|
||||
|
||||
// (y2 - y1) * 1 / (x2 - x1)
|
||||
component mult = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== sub2.out;
|
||||
mult.in[1] <== modInv.out;
|
||||
mult.dummy <== dummy;
|
||||
|
||||
// (y2 - y1) * 1 / (x2 - x1) % P ==> λ
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod.base <== mult.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
// λ * λ
|
||||
component mult2 = BigMultOptimisedOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== mod.mod;
|
||||
mult2.in[1] <== mod.mod;
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
// P - in1
|
||||
component sub3 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub3.in1 <== P;
|
||||
sub3.in2 <== in1[0];
|
||||
sub3.modulus <== P;
|
||||
sub3.dummy <== dummy;
|
||||
|
||||
// P - in2
|
||||
component sub4 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub4.in1 <== P;
|
||||
sub4.in2 <== in2[0];
|
||||
sub4.modulus <== P;
|
||||
sub4.dummy <== dummy;
|
||||
|
||||
// 2 * P - in1 - in2
|
||||
component add = BigAddOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
add.in[0] <== sub3.out;
|
||||
add.in[1] <== sub4.out;
|
||||
add.dummy <== dummy;
|
||||
|
||||
// λ * λ + 2 * P - in1 - in2
|
||||
component add2 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add2.in1 <== mult2.out;
|
||||
add2.in2 <== add.out;
|
||||
add2.dummy <== dummy;
|
||||
|
||||
// (λ * λ + 2 * P - in1 - in2) % P ==> x3
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod2.base <== add2.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
out[0] <== mod2.mod;
|
||||
|
||||
@@ -515,32 +446,27 @@ template EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
sub5.in1 <== in1[0];
|
||||
sub5.in2 <== out[0];
|
||||
sub5.modulus <== P;
|
||||
sub5.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3)
|
||||
component mult3 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
mult3.in1 <== mult.out;
|
||||
mult3.in2 <== sub5.out;
|
||||
mult3.dummy <== dummy;
|
||||
|
||||
// P - y1
|
||||
component sub6 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub6.in1 <== P;
|
||||
sub6.in2 <== in1[1];
|
||||
sub6.modulus <== P;
|
||||
sub6.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3) + P - y1
|
||||
component add3 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER);
|
||||
add3.in1 <== mult3.out;
|
||||
add3.in2 <== sub6.out;
|
||||
add3.dummy <== dummy;
|
||||
|
||||
// (λ * (x1 - x3) + P - y1) % P ==> y3
|
||||
component mod3 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod3.base <== add3.out;
|
||||
mod3.modulus <== P;
|
||||
mod3.dummy <== dummy;
|
||||
|
||||
out[1] <== mod3.mod;
|
||||
}
|
||||
@@ -556,7 +482,6 @@ template EllipicCurveScalarGeneratorMultiplicationOptimised(CHUNK_SIZE, CHUNK_NU
|
||||
assert(CHUNK_SIZE == 64 && CHUNK_NUMBER == 4);
|
||||
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
@@ -564,7 +489,6 @@ template EllipicCurveScalarGeneratorMultiplicationOptimised(CHUNK_SIZE, CHUNK_NU
|
||||
|
||||
var parts = CHUNK_NUMBER * CHUNK_SIZE \ STRIDE;
|
||||
|
||||
dummy * dummy === 0;
|
||||
var powers[parts][2 ** STRIDE][2][CHUNK_NUMBER];
|
||||
if (P[0] == 18446744069414583343 && P[1] == 18446744073709551615 && P[2] == 18446744073709551615 && P[3] == 18446744073709551615){
|
||||
powers = get_g_pow_stride8_table_secp256k1(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
@@ -614,7 +538,6 @@ template EllipicCurveScalarGeneratorMultiplicationOptimised(CHUNK_SIZE, CHUNK_NU
|
||||
for (var j = 0; j < 2; j++){
|
||||
for (var axis_idx = 0; axis_idx < CHUNK_NUMBER; axis_idx++){
|
||||
getSumOfNElements[i][j][axis_idx] = GetSumOfNElements(2 ** STRIDE);
|
||||
getSumOfNElements[i][j][axis_idx].dummy <== dummy;
|
||||
for (var stride_idx = 0; stride_idx < 2 ** STRIDE; stride_idx++){
|
||||
getSumOfNElements[i][j][axis_idx].in[stride_idx] <== resultCoordinateComputation[i][stride_idx][j][axis_idx];
|
||||
}
|
||||
@@ -625,7 +548,7 @@ template EllipicCurveScalarGeneratorMultiplicationOptimised(CHUNK_SIZE, CHUNK_NU
|
||||
component isZero[parts];
|
||||
for (var i = 0; i < parts; i++){
|
||||
isZero[i] = IsZero();
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out + dummy * dummy;
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out;
|
||||
}
|
||||
|
||||
signal precomptedDummy[parts][2][CHUNK_NUMBER];
|
||||
@@ -663,7 +586,6 @@ template EllipicCurveScalarGeneratorMultiplicationOptimised(CHUNK_SIZE, CHUNK_NU
|
||||
|
||||
for (var i = 0; i < parts - 1; i++){
|
||||
adders[i] = EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i].dummy <== dummy;
|
||||
isDummyLeft[i] = IsEqual();
|
||||
isDummyRight[i] = IsEqual();
|
||||
|
||||
@@ -741,7 +663,6 @@ template EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZ
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
@@ -751,7 +672,6 @@ template EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZ
|
||||
|
||||
component precompute = EllipticCurvePrecomputePipinger(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZE);
|
||||
precompute.in <== in;
|
||||
precompute.dummy <== dummy;
|
||||
precompute.out ==> precomputed;
|
||||
|
||||
var DOUBLERS_NUMBER = CHUNK_SIZE * CHUNK_NUMBER - WINDOW_SIZE;
|
||||
@@ -866,14 +786,12 @@ template EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, WINDOW_SIZ
|
||||
|
||||
adders[i \ WINDOW_SIZE].in1 <== res [i \ WINDOW_SIZE];
|
||||
adders[i \ WINDOW_SIZE].in2 <== tmp2[i \ WINDOW_SIZE];
|
||||
adders[i \ WINDOW_SIZE].dummy <== dummy;
|
||||
res[i \ WINDOW_SIZE + 1] <== tmp2[i \ WINDOW_SIZE];
|
||||
|
||||
} else {
|
||||
|
||||
adders[i \ WINDOW_SIZE].in1 <== doublers[i - 1].out;
|
||||
adders[i \ WINDOW_SIZE].in2 <== tmp2[i \ WINDOW_SIZE];
|
||||
adders[i \ WINDOW_SIZE].dummy <== dummy;
|
||||
|
||||
zeroEquals[i \ WINDOW_SIZE] = IsEqual();
|
||||
|
||||
@@ -923,12 +841,10 @@ template EllipicCurveScalarPrecomputeMultiplicationOptimised(CHUNK_SIZE, CHUNK_N
|
||||
var parts = CHUNK_NUMBER * CHUNK_SIZE \ STRIDE;
|
||||
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input powers[parts][2 ** STRIDE][2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// We don`t use point anywhere, we should add any quadratic constraint for secure issues
|
||||
@@ -977,7 +893,6 @@ template EllipicCurveScalarPrecomputeMultiplicationOptimised(CHUNK_SIZE, CHUNK_N
|
||||
for (var j = 0; j < 2; j++){
|
||||
for (var axis_idx = 0; axis_idx < CHUNK_NUMBER; axis_idx++){
|
||||
getSumOfNElements[i][j][axis_idx] = GetSumOfNElements(2 ** STRIDE);
|
||||
getSumOfNElements[i][j][axis_idx].dummy <== dummy;
|
||||
for (var stride_idx = 0; stride_idx < 2 ** STRIDE; stride_idx++){
|
||||
getSumOfNElements[i][j][axis_idx].in[stride_idx] <== resultCoordinateComputation[i][stride_idx][j][axis_idx];
|
||||
}
|
||||
@@ -988,7 +903,7 @@ template EllipicCurveScalarPrecomputeMultiplicationOptimised(CHUNK_SIZE, CHUNK_N
|
||||
component isZero[parts];
|
||||
for (var i = 0; i < parts; i++){
|
||||
isZero[i] = IsZero();
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out + dummy * dummy;
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out;
|
||||
}
|
||||
|
||||
signal precomptedDummy[parts][2][CHUNK_NUMBER];
|
||||
@@ -1026,7 +941,6 @@ template EllipicCurveScalarPrecomputeMultiplicationOptimised(CHUNK_SIZE, CHUNK_N
|
||||
|
||||
for (var i = 0; i < parts - 1; i++){
|
||||
adders[i] = EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i].dummy <== dummy;
|
||||
isDummyLeft[i] = IsEqual();
|
||||
isDummyRight[i] = IsEqual();
|
||||
|
||||
@@ -1101,48 +1015,38 @@ template PointOnCurveNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
assert(CHUNK_SIZE == 64);
|
||||
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
component mult = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== in[0];
|
||||
mult.in[1] <== in[0];
|
||||
mult.dummy <== dummy;
|
||||
|
||||
component mult2 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
mult2.in1 <== mult.out;
|
||||
mult2.in2 <== in[0];
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
component mult3 = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult3.in[0] <== in[0];
|
||||
mult3.in[1] <== A;
|
||||
mult3.dummy <== dummy;
|
||||
|
||||
component mult4 = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult4.in[0] <== in[1];
|
||||
mult4.in[1] <== in[1];
|
||||
mult4.dummy <== dummy;
|
||||
|
||||
component add = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER * 2 - 1);
|
||||
add.in1 <== mult2.out;
|
||||
add.in2 <== mult3.out;
|
||||
add.dummy <== dummy;
|
||||
|
||||
component add2 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER);
|
||||
add2.in1 <== add.out;
|
||||
add2.in2 <== B;
|
||||
add2.dummy <== dummy;
|
||||
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod.base <== mult4.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod2.base <== add2.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
mod.mod[i] === mod2.mod[i];
|
||||
@@ -1157,14 +1061,11 @@ template PointOnCurveNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
template EllipticCurveDoubleNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
// x * x
|
||||
component mult = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== in[0];
|
||||
mult.in[1] <== in[0];
|
||||
mult.dummy <== dummy;
|
||||
|
||||
// 3 * x * x
|
||||
component scalarMult = ScalarMultOverflow(CHUNK_NUMBER * 2 - 1);
|
||||
@@ -1175,7 +1076,6 @@ template EllipticCurveDoubleNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component add = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add.in1 <== scalarMult.out;
|
||||
add.in2 <== A;
|
||||
add.dummy <== dummy;
|
||||
|
||||
// 2 * y
|
||||
component scalarMult2 = ScalarMultOverflow(CHUNK_NUMBER);
|
||||
@@ -1186,32 +1086,27 @@ template EllipticCurveDoubleNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component modInv = BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
modInv.in <== scalarMult2.out;
|
||||
modInv.modulus <== P;
|
||||
modInv.dummy <== dummy;
|
||||
|
||||
// (3 * x * x + a) * 1 / (2 * y)
|
||||
component mult2 = BigMultNonEqualOverflow(CHUNK_SIZE, 2 * CHUNK_NUMBER - 1, CHUNK_NUMBER);
|
||||
mult2.in1 <== add.out;
|
||||
mult2.in2 <== modInv.out;
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
// ((3 * x * x + a) * 1 / (2 * y)) % p ==> λ
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod.base <== mult2.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
// λ * λ
|
||||
component mult3 = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult3.in[0] <== mod.mod;
|
||||
mult3.in[1] <== mod.mod;
|
||||
mult3.dummy <== dummy;
|
||||
|
||||
// P - x
|
||||
component sub = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub.in1 <== P;
|
||||
sub.in2 <== in[0];
|
||||
sub.modulus <== P;
|
||||
sub.dummy <== dummy;
|
||||
|
||||
// 2 * P - 2 * x
|
||||
component scalarMult3 = ScalarMultOverflow(CHUNK_NUMBER);
|
||||
@@ -1222,13 +1117,11 @@ template EllipticCurveDoubleNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
component add2 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add2.in1 <== mult3.out;
|
||||
add2.in2 <== scalarMult3.out;
|
||||
add2.dummy <== dummy;
|
||||
|
||||
// (λ * λ + 2 * P - 2 * x) % p ==> x3
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod2.base <== add2.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
out[0] <== mod2.mod;
|
||||
|
||||
@@ -1237,32 +1130,27 @@ template EllipticCurveDoubleNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
sub2.in1 <== in[0];
|
||||
sub2.in2 <== out[0];
|
||||
sub2.modulus <== P;
|
||||
sub2.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3)
|
||||
component mult4 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
mult4.in1 <== mod.mod;
|
||||
mult4.in2 <== sub2.out;
|
||||
mult4.dummy <== dummy;
|
||||
|
||||
// P - y
|
||||
component sub3 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub3.in1 <== P;
|
||||
sub3.in2 <== in[1];
|
||||
sub3.modulus <== P;
|
||||
sub3.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3) + P - y
|
||||
component add3 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add3.in1 <== mult4.out;
|
||||
add3.in2 <== sub3.out;
|
||||
add3.dummy <== dummy;
|
||||
|
||||
// (λ * (x1 - x3) + P - y) % P ==> y3
|
||||
component mod3 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod3.base <== add3.out;
|
||||
mod3.modulus <== P;
|
||||
mod3.dummy <== dummy;
|
||||
|
||||
out[1] <== mod3.mod;
|
||||
}
|
||||
@@ -1276,78 +1164,65 @@ template EllipticCurveAddNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in1[2][CHUNK_NUMBER];
|
||||
signal input in2[2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
// x2 - x1
|
||||
component sub = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub.in1 <== in2[0];
|
||||
sub.in2 <== in1[0];
|
||||
sub.modulus <== P;
|
||||
sub.dummy <== dummy;
|
||||
|
||||
// y2 - y1
|
||||
component sub2 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub2.in1 <== in2[1];
|
||||
sub2.in2 <== in1[1];
|
||||
sub2.modulus <== P;
|
||||
sub2.dummy <== dummy;
|
||||
|
||||
// (x2 - x1) ** -1
|
||||
component modInv = BigModInvOverflow(CHUNK_SIZE, CHUNK_NUMBER, CHUNK_NUMBER);
|
||||
modInv.in <== sub.out;
|
||||
modInv.modulus <== P;
|
||||
modInv.dummy <== dummy;
|
||||
|
||||
// (y2 - y1) * 1 / (x2 - x1)
|
||||
component mult = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult.in[0] <== sub2.out;
|
||||
mult.in[1] <== modInv.out;
|
||||
mult.dummy <== dummy;
|
||||
|
||||
// (y2 - y1) * 1 / (x2 - x1) % P ==> λ
|
||||
component mod = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod.base <== mult.out;
|
||||
mod.modulus <== P;
|
||||
mod.dummy <== dummy;
|
||||
|
||||
// λ * λ
|
||||
component mult2 = BigMultOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== mod.mod;
|
||||
mult2.in[1] <== mod.mod;
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
// P - in1
|
||||
component sub3 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub3.in1 <== P;
|
||||
sub3.in2 <== in1[0];
|
||||
sub3.modulus <== P;
|
||||
sub3.dummy <== dummy;
|
||||
|
||||
// P - in2
|
||||
component sub4 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub4.in1 <== P;
|
||||
sub4.in2 <== in2[0];
|
||||
sub4.modulus <== P;
|
||||
sub4.dummy <== dummy;
|
||||
|
||||
// 2 * P - in1 - in2
|
||||
component add = BigAddOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
add.in[0] <== sub3.out;
|
||||
add.in[1] <== sub4.out;
|
||||
add.dummy <== dummy;
|
||||
|
||||
// λ * λ + 2 * P - in1 - in2
|
||||
component add2 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
add2.in1 <== mult2.out;
|
||||
add2.in2 <== add.out;
|
||||
add2.dummy <== dummy;
|
||||
|
||||
// (λ * λ + 2 * P - in1 - in2) % P ==> x3
|
||||
component mod2 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER, 2);
|
||||
mod2.base <== add2.out;
|
||||
mod2.modulus <== P;
|
||||
mod2.dummy <== dummy;
|
||||
|
||||
out[0] <== mod2.mod;
|
||||
|
||||
@@ -1356,32 +1231,27 @@ template EllipticCurveAddNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
sub5.in1 <== in1[0];
|
||||
sub5.in2 <== out[0];
|
||||
sub5.modulus <== P;
|
||||
sub5.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3)
|
||||
component mult3 = BigMultNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 2 - 1, CHUNK_NUMBER);
|
||||
mult3.in1 <== mult.out;
|
||||
mult3.in2 <== sub5.out;
|
||||
mult3.dummy <== dummy;
|
||||
|
||||
// P - y1
|
||||
component sub6 = BigSubModOverflow(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
sub6.in1 <== P;
|
||||
sub6.in2 <== in1[1];
|
||||
sub6.modulus <== P;
|
||||
sub6.dummy <== dummy;
|
||||
|
||||
// λ * (x1 - x3) + P - y1
|
||||
component add3 = BigAddNonEqualOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER);
|
||||
add3.in1 <== mult3.out;
|
||||
add3.in2 <== sub6.out;
|
||||
add3.dummy <== dummy;
|
||||
|
||||
// (λ * (x1 - x3) + P - y1) % P ==> y3
|
||||
component mod3 = BigModOverflow(CHUNK_SIZE, CHUNK_NUMBER * 3 - 2, CHUNK_NUMBER, 3);
|
||||
mod3.base <== add3.out;
|
||||
mod3.modulus <== P;
|
||||
mod3.dummy <== dummy;
|
||||
|
||||
out[1] <== mod3.mod;
|
||||
}
|
||||
@@ -1396,7 +1266,6 @@ template EllipticCurveAddNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
// Complexity is field \ 8 - 1 additions
|
||||
template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
@@ -1404,7 +1273,6 @@ template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK
|
||||
|
||||
var parts = CHUNK_NUMBER * CHUNK_SIZE \ STRIDE;
|
||||
|
||||
dummy * dummy === 0;
|
||||
var powers[parts][2 ** STRIDE][2][CHUNK_NUMBER];
|
||||
if (CHUNK_NUMBER == 6){
|
||||
if (P[0] == 9747760000893709395 && P[1] == 12453481191562877553 && P[2] == 1347097566612230435 && P[3] == 1526563086152259252 && P[4] == 1107163671716839903 && P[5] == 10140169582434348328){
|
||||
@@ -1466,7 +1334,6 @@ template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK
|
||||
for (var j = 0; j < 2; j++){
|
||||
for (var axis_idx = 0; axis_idx < CHUNK_NUMBER; axis_idx++){
|
||||
getSumOfNElements[i][j][axis_idx] = GetSumOfNElements(2 ** STRIDE);
|
||||
getSumOfNElements[i][j][axis_idx].dummy <== dummy;
|
||||
for (var stride_idx = 0; stride_idx < 2 ** STRIDE; stride_idx++){
|
||||
getSumOfNElements[i][j][axis_idx].in[stride_idx] <== resultCoordinateComputation[i][stride_idx][j][axis_idx];
|
||||
}
|
||||
@@ -1477,7 +1344,7 @@ template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK
|
||||
component isZero[parts];
|
||||
for (var i = 0; i < parts; i++){
|
||||
isZero[i] = IsZero();
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out + dummy * dummy;
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out;
|
||||
}
|
||||
|
||||
signal precomptedDummy[parts][2][CHUNK_NUMBER];
|
||||
@@ -1515,7 +1382,6 @@ template EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK
|
||||
|
||||
for (var i = 0; i < parts - 1; i++){
|
||||
adders[i] = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i].dummy <== dummy;
|
||||
isDummyLeft[i] = IsEqual();
|
||||
isDummyRight[i] = IsEqual();
|
||||
|
||||
@@ -1602,12 +1468,10 @@ template EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUN
|
||||
var parts = CHUNK_NUMBER * CHUNK_SIZE \ STRIDE;
|
||||
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input powers[parts][2 ** STRIDE][2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// We don`t use point anywhere, we should add any quadratic constraint for secure issues
|
||||
@@ -1656,7 +1520,6 @@ template EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUN
|
||||
for (var j = 0; j < 2; j++){
|
||||
for (var axis_idx = 0; axis_idx < CHUNK_NUMBER; axis_idx++){
|
||||
getSumOfNElements[i][j][axis_idx] = GetSumOfNElements(2 ** STRIDE);
|
||||
getSumOfNElements[i][j][axis_idx].dummy <== dummy;
|
||||
for (var stride_idx = 0; stride_idx < 2 ** STRIDE; stride_idx++){
|
||||
getSumOfNElements[i][j][axis_idx].in[stride_idx] <== resultCoordinateComputation[i][stride_idx][j][axis_idx];
|
||||
}
|
||||
@@ -1667,7 +1530,7 @@ template EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUN
|
||||
component isZero[parts];
|
||||
for (var i = 0; i < parts; i++){
|
||||
isZero[i] = IsZero();
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out + dummy * dummy;
|
||||
isZero[i].in <== getSumOfNElements[i][0][0].out + getSumOfNElements[i][0][1].out + getSumOfNElements[i][0][2].out + getSumOfNElements[i][0][3].out + getSumOfNElements[i][1][0].out + getSumOfNElements[i][1][1].out + getSumOfNElements[i][1][2].out + getSumOfNElements[i][1][3].out;
|
||||
}
|
||||
|
||||
signal precomptedDummy[parts][2][CHUNK_NUMBER];
|
||||
@@ -1705,7 +1568,6 @@ template EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUN
|
||||
|
||||
for (var i = 0; i < parts - 1; i++){
|
||||
adders[i] = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
adders[i].dummy <== dummy;
|
||||
isDummyLeft[i] = IsEqual();
|
||||
isDummyRight[i] = IsEqual();
|
||||
|
||||
@@ -1773,36 +1635,28 @@ template EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUN
|
||||
|
||||
template PointOnCurve(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
if (CHUNK_NUMBER == 4 && CHUNK_SIZE == 64){
|
||||
component pointOnCurveOptimised = PointOnCurveOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
pointOnCurveOptimised.in <== in;
|
||||
pointOnCurveOptimised.dummy <== dummy;
|
||||
} else {
|
||||
component pointOnCurveNonOptimised = PointOnCurveNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
pointOnCurveNonOptimised.in <== in;
|
||||
pointOnCurveNonOptimised.dummy <== dummy;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template EllipticCurveDouble(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
if (CHUNK_NUMBER == 4 && CHUNK_SIZE == 64){
|
||||
component ecDoubleOptimised = EllipticCurveDoubleOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
ecDoubleOptimised.in <== in;
|
||||
ecDoubleOptimised.dummy <== dummy;
|
||||
out <== ecDoubleOptimised.out;
|
||||
} else {
|
||||
component ecDoubleNonOptimised = EllipticCurveDoubleNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
ecDoubleNonOptimised.in <== in;
|
||||
ecDoubleNonOptimised.dummy <== dummy;
|
||||
out <== ecDoubleNonOptimised.out;
|
||||
}
|
||||
}
|
||||
@@ -1810,40 +1664,32 @@ template EllipticCurveDouble(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
template EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input in1[2][CHUNK_NUMBER];
|
||||
signal input in2[2][CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
if (CHUNK_NUMBER == 4 && CHUNK_SIZE == 64){
|
||||
component ecAddOptimised = EllipticCurveAddOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
ecAddOptimised.in1 <== in1;
|
||||
ecAddOptimised.in2 <== in2;
|
||||
ecAddOptimised.dummy <== dummy;
|
||||
out <== ecAddOptimised.out;
|
||||
} else {
|
||||
component ecAddNonOptimised = EllipticCurveAddNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
ecAddNonOptimised.in1 <== in1;
|
||||
ecAddNonOptimised.in2 <== in2;
|
||||
ecAddNonOptimised.dummy <== dummy;
|
||||
out <== ecAddNonOptimised.out;
|
||||
}
|
||||
}
|
||||
|
||||
template EllipicCurveScalarGeneratorMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
if (CHUNK_SIZE == 64 && CHUNK_NUMBER == 4){
|
||||
component ecGenMultOptimised = EllipicCurveScalarGeneratorMultiplicationOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
ecGenMultOptimised.scalar <== scalar;
|
||||
ecGenMultOptimised.dummy <== dummy;
|
||||
out <== ecGenMultOptimised.out;
|
||||
} else {
|
||||
component ecGenMultNonOptimised = EllipicCurveScalarGeneratorMultiplicationNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
ecGenMultNonOptimised.scalar <== scalar;
|
||||
ecGenMultNonOptimised.dummy <== dummy;
|
||||
out <== ecGenMultNonOptimised.out;
|
||||
}
|
||||
|
||||
@@ -1856,26 +1702,22 @@ template EllipicCurveScalarPrecomputeMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A,
|
||||
var parts = CHUNK_NUMBER * CHUNK_SIZE \ STRIDE;
|
||||
|
||||
signal input scalar[CHUNK_NUMBER];
|
||||
signal input dummy;
|
||||
signal input in[2][CHUNK_NUMBER];
|
||||
signal input powers[parts][2 ** STRIDE][2][CHUNK_NUMBER];
|
||||
signal output out[2][CHUNK_NUMBER];
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
if (CHUNK_SIZE == 64 && CHUNK_NUMBER == 4){
|
||||
component scalarMultOptimised = EllipicCurveScalarPrecomputeMultiplicationOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
scalarMultOptimised.in <== in;
|
||||
scalarMultOptimised.scalar <== scalar;
|
||||
scalarMultOptimised.powers <== powers;
|
||||
scalarMultOptimised.dummy <== dummy;
|
||||
out <== scalarMultOptimised.out;
|
||||
} else {
|
||||
component scalarMultNonOptimised = EllipicCurveScalarPrecomputeMultiplicationNonOptimised(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
scalarMultNonOptimised.in <== in;
|
||||
scalarMultNonOptimised.scalar <== scalar;
|
||||
scalarMultNonOptimised.powers <== powers;
|
||||
scalarMultNonOptimised.dummy <== dummy;
|
||||
out <== scalarMultNonOptimised.out;
|
||||
|
||||
}
|
||||
|
||||
@@ -49,11 +49,9 @@ template EllipticCurveGetGenerator(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
}
|
||||
}
|
||||
|
||||
// Get "dummy" point
|
||||
// We can`t "if" signal in circom, so we always need to do all opertions, even we won`t use results of them
|
||||
// For example, in scalar mult we can have case where we shouln`t add anything (bits = [0,0, .. ,0])
|
||||
// We will ignore result, but we still should get it, so we need to pout something anyway
|
||||
// We use this dummy point for such purposes
|
||||
// Dummy point = G * 2**256
|
||||
template EllipticCurveGetDummy(CHUNK_SIZE, CHUNK_NUMBER, A, B, P){
|
||||
signal output dummyPoint[2][CHUNK_NUMBER];
|
||||
|
||||
@@ -33,37 +33,31 @@ template ShaHashChunks(BLOCK_NUM, ALGO){
|
||||
BLOCK_SIZE = 1024;
|
||||
}
|
||||
signal input in[BLOCK_SIZE * BLOCK_NUM];
|
||||
signal input dummy;
|
||||
signal output out[ALGO];
|
||||
|
||||
if (ALGO == 160) {
|
||||
component hash160 = Sha1HashChunks(BLOCK_NUM);
|
||||
hash160.in <== in;
|
||||
hash160.dummy <== dummy;
|
||||
hash160.out ==> out;
|
||||
}
|
||||
if (ALGO == 224) {
|
||||
component hash224 = Sha224HashChunks(BLOCK_NUM);
|
||||
hash224.in <== in;
|
||||
hash224.dummy <== dummy;
|
||||
hash224.out ==> out;
|
||||
}
|
||||
if (ALGO == 256) {
|
||||
component hash256 = Sha256HashChunks(BLOCK_NUM);
|
||||
hash256.in <== in;
|
||||
hash256.dummy <== dummy;
|
||||
hash256.out ==> out;
|
||||
}
|
||||
if (ALGO == 384) {
|
||||
component hash384 = Sha384HashChunks(BLOCK_NUM);
|
||||
hash384.in <== in;
|
||||
hash384.dummy <== dummy;
|
||||
hash384.out ==> out;
|
||||
}
|
||||
if (ALGO == 512) {
|
||||
component hash512 = Sha512HashChunks(BLOCK_NUM);
|
||||
hash512.in <== in;
|
||||
hash512.dummy <== dummy;
|
||||
hash512.out ==> out;
|
||||
}
|
||||
}
|
||||
@@ -76,37 +70,31 @@ template ShaHashBits(LEN, ALGO){
|
||||
BLOCK_SIZE = 1024;
|
||||
}
|
||||
signal input in[LEN];
|
||||
signal input dummy;
|
||||
signal output out[ALGO];
|
||||
|
||||
if (ALGO == 160) {
|
||||
component hash160 = Sha1HashBits(LEN);
|
||||
hash160.in <== in;
|
||||
hash160.dummy <== dummy;
|
||||
hash160.out ==> out;
|
||||
}
|
||||
if (ALGO == 224) {
|
||||
component hash224 = Sha224HashBits(LEN);
|
||||
hash224.in <== in;
|
||||
hash224.dummy <== dummy;
|
||||
hash224.out ==> out;
|
||||
}
|
||||
if (ALGO == 256) {
|
||||
component hash256 = Sha256HashBits(LEN);
|
||||
hash256.in <== in;
|
||||
hash256.dummy <== dummy;
|
||||
hash256.out ==> out;
|
||||
}
|
||||
if (ALGO == 384) {
|
||||
component hash384 = Sha384HashBits(LEN);
|
||||
hash384.in <== in;
|
||||
hash384.dummy <== dummy;
|
||||
hash384.out ==> out;
|
||||
}
|
||||
if (ALGO == 512) {
|
||||
component hash512 = Sha512HashBits(LEN);
|
||||
hash512.in <== in;
|
||||
hash512.dummy <== dummy;
|
||||
hash512.out ==> out;
|
||||
}
|
||||
}
|
||||
@@ -121,12 +109,9 @@ template PoseidonHash(LEN){
|
||||
assert (LEN <= 16);
|
||||
assert (LEN > 0);
|
||||
signal input in[LEN];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out;
|
||||
|
||||
component poseidon = Poseidon(LEN);
|
||||
poseidon.in <== in;
|
||||
poseidon.dummy <== dummy;
|
||||
out <== poseidon.out;
|
||||
}
|
||||
|
||||
@@ -31,15 +31,12 @@ template Ark(t, C, r) {
|
||||
|
||||
template Mix(t, M) {
|
||||
signal input in[t];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[t];
|
||||
|
||||
component sum[t];
|
||||
|
||||
for (var i = 0; i < t; i++) {
|
||||
sum[i] = GetSumOfNElements(t);
|
||||
sum[i].dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
sum[i].in[j] <== M[j][i] * in[j];
|
||||
}
|
||||
@@ -49,12 +46,9 @@ template Mix(t, M) {
|
||||
|
||||
template MixLast(t, M, s) {
|
||||
signal input in[t];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out;
|
||||
|
||||
component sum = GetSumOfNElements(t);
|
||||
sum.dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
sum.in[j] <== M[j][s] * in[j];
|
||||
}
|
||||
@@ -63,28 +57,23 @@ template MixLast(t, M, s) {
|
||||
|
||||
template MixS(t, S, r) {
|
||||
signal input in[t];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[t];
|
||||
|
||||
|
||||
component sum = GetSumOfNElements(t);
|
||||
sum.dummy <== dummy;
|
||||
for (var i = 0; i < t; i++) {
|
||||
sum.in[i] <== S[(t * 2 - 1) * r + i] * in[i];
|
||||
}
|
||||
out[0] <== sum.out;
|
||||
|
||||
for (var i = 1; i < t; i++) {
|
||||
out[i] <== in[i] + in[0] * S[(t * 2 - 1) * r + t + i - 1] + dummy * dummy;
|
||||
out[i] <== in[i] + in[0] * S[(t * 2 - 1) * r + t + i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
template PoseidonEx(nInputs, nOuts) {
|
||||
signal input inputs[nInputs];
|
||||
signal input initialState;
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[nOuts];
|
||||
|
||||
@@ -130,7 +119,6 @@ template PoseidonEx(nInputs, nOuts) {
|
||||
}
|
||||
|
||||
mix[r] = Mix(t,M);
|
||||
mix[r].dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
mix[r].in[j] <== ark[r + 1].out[j];
|
||||
}
|
||||
@@ -148,7 +136,6 @@ template PoseidonEx(nInputs, nOuts) {
|
||||
}
|
||||
|
||||
mix[nRoundsF \ 2 - 1] = Mix(t,P);
|
||||
mix[nRoundsF \ 2 - 1].dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
mix[nRoundsF \ 2 - 1].in[j] <== ark[nRoundsF \ 2].out[j];
|
||||
}
|
||||
@@ -163,7 +150,6 @@ template PoseidonEx(nInputs, nOuts) {
|
||||
}
|
||||
|
||||
mixS[r] = MixS(t, S, r);
|
||||
mixS[r].dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
if (j == 0) {
|
||||
mixS[r].in[j] <== sigmaP[r].out + C[(nRoundsF \ 2 + 1) * t + r];
|
||||
@@ -193,7 +179,6 @@ template PoseidonEx(nInputs, nOuts) {
|
||||
}
|
||||
|
||||
mix[nRoundsF \ 2 + r] = Mix(t,M);
|
||||
mix[nRoundsF \ 2 + r].dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
mix[nRoundsF \ 2 + r].in[j] <== ark[nRoundsF \ 2 + r + 1].out[j];
|
||||
}
|
||||
@@ -207,7 +192,6 @@ template PoseidonEx(nInputs, nOuts) {
|
||||
|
||||
for (var i = 0; i < nOuts; i++) {
|
||||
mixLast[i] = MixLast(t,M,i);
|
||||
mixLast[i].dummy <== dummy;
|
||||
for (var j = 0; j < t; j++) {
|
||||
mixLast[i].in[j] <== sigmaF[nRoundsF - 1][j].out;
|
||||
}
|
||||
@@ -221,12 +205,9 @@ template PoseidonEx(nInputs, nOuts) {
|
||||
// Use this template to calculate to calculate Poseidon hash of your vector (1 elememnt array for one num)
|
||||
template Poseidon(nInputs) {
|
||||
signal input in[nInputs];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out;
|
||||
|
||||
component pEx = PoseidonEx(nInputs, 1);
|
||||
pEx.dummy <== dummy;
|
||||
pEx.initialState <== 0;
|
||||
for (var i = 0; i < nInputs; i++) {
|
||||
pEx.inputs[i] <== in[i];
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
// Constant generation for poseidon hash
|
||||
// Don`t change this without understanding what are u doing!!!
|
||||
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
||||
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||
|
||||
function POSEIDON_C(t) {
|
||||
if (t==2) {
|
||||
return
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../../bitify/bitify.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
template H(x) {
|
||||
template H_sha1(x) {
|
||||
signal output out[32];
|
||||
var c[5] = [
|
||||
0x67452301,
|
||||
@@ -20,7 +20,7 @@ template H(x) {
|
||||
}
|
||||
}
|
||||
|
||||
template K(t) {
|
||||
template K_sha1(t) {
|
||||
signal output out[32];
|
||||
var k[4] = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
|
||||
|
||||
|
||||
@@ -5,25 +5,22 @@ include "sha1compression.circom";
|
||||
include "../sha2/sha2Common.circom";
|
||||
|
||||
template Sha1HashChunks(BLOCK_NUM) {
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal input in[BLOCK_NUM * 512];
|
||||
signal output out[160];
|
||||
|
||||
var i;
|
||||
var k;
|
||||
|
||||
component ha0 = H(0);
|
||||
component hb0 = H(1);
|
||||
component hc0 = H(2);
|
||||
component hd0 = H(3);
|
||||
component he0 = H(4);
|
||||
component ha0 = H_sha1(0);
|
||||
component hb0 = H_sha1(1);
|
||||
component hc0 = H_sha1(2);
|
||||
component hd0 = H_sha1(3);
|
||||
component he0 = H_sha1(4);
|
||||
|
||||
component sha1Compression[BLOCK_NUM];
|
||||
|
||||
for (i = 0; i < BLOCK_NUM; i++) {
|
||||
sha1Compression[i] = Sha1compression();
|
||||
sha1Compression[i].dummy <== dummy;
|
||||
|
||||
if (i == 0) {
|
||||
for (k = 0; k < 32; k++) {
|
||||
@@ -56,8 +53,6 @@ template Sha1HashChunks(BLOCK_NUM) {
|
||||
}
|
||||
|
||||
template Sha1HashBits(LEN) {
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal input in[LEN];
|
||||
signal output out[160];
|
||||
|
||||
@@ -69,17 +64,16 @@ template Sha1HashBits(LEN) {
|
||||
var i;
|
||||
var k;
|
||||
|
||||
component ha0 = H(0);
|
||||
component hb0 = H(1);
|
||||
component hc0 = H(2);
|
||||
component hd0 = H(3);
|
||||
component he0 = H(4);
|
||||
component ha0 = H_sha1(0);
|
||||
component hb0 = H_sha1(1);
|
||||
component hc0 = H_sha1(2);
|
||||
component hd0 = H_sha1(3);
|
||||
component he0 = H_sha1(4);
|
||||
|
||||
component sha1Compression[BLOCK_NUM];
|
||||
|
||||
for (i = 0; i < BLOCK_NUM; i++) {
|
||||
sha1Compression[i] = Sha1compression();
|
||||
sha1Compression[i].dummy <== dummy;
|
||||
|
||||
if (i == 0) {
|
||||
for (k = 0; k < 32; k++) {
|
||||
|
||||
@@ -9,8 +9,6 @@ include "../../bitify/operations.circom";
|
||||
template Sha1compression() {
|
||||
signal input hin[160];
|
||||
signal input inp[512];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[160];
|
||||
|
||||
signal a[81][32];
|
||||
@@ -39,20 +37,18 @@ template Sha1compression() {
|
||||
|
||||
component kT[80];
|
||||
for (i = 0; i <= 79; i++){
|
||||
kT[i] = K(i);
|
||||
kT[i] = K_sha1(i);
|
||||
}
|
||||
|
||||
component tTmp[80];
|
||||
for (i = 0; i <= 79; i++){
|
||||
tTmp[i] = T(i);
|
||||
tTmp[i].dummy <== dummy;
|
||||
|
||||
}
|
||||
|
||||
component fSum[5];
|
||||
for (i = 0; i < 5; i++){
|
||||
fSum[i] = BinSum(2, 32);
|
||||
fSum[i].dummy <== dummy;
|
||||
fSum[i] = BinSum_sha1(2, 32);
|
||||
}
|
||||
|
||||
for (var t = 0; t <= 15; t++) {
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "./rotate.circom";
|
||||
include "../../bitify/comparators.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "./f.circom";
|
||||
include "./constants.circom";
|
||||
include "../../int/arithmetic.circom";
|
||||
|
||||
template T(t) {
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal input a[32];
|
||||
signal input b[32];
|
||||
@@ -31,8 +29,7 @@ template T(t) {
|
||||
f.d[k] <== d[k];
|
||||
}
|
||||
|
||||
component sumBinary = BinSum(5, 32);
|
||||
sumBinary.dummy <== dummy;
|
||||
component sumBinary = BinSum_sha1(5, 32);
|
||||
var nout = 35;
|
||||
|
||||
for (k = 0; k < 32; k++) {
|
||||
|
||||
@@ -8,8 +8,6 @@ include "sha224InitialValue.circom";
|
||||
template Sha224HashBits(LEN) {
|
||||
|
||||
signal input in[LEN];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[224];
|
||||
|
||||
component addPadding = ShaPadding(LEN, 512);
|
||||
@@ -28,9 +26,7 @@ template Sha224HashBits(LEN) {
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
|
||||
sch[m] = Sha2_224_256Shedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_224_256Rounds(64);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 32; i++) {
|
||||
|
||||
@@ -8,8 +8,6 @@ include "sha224InitialValue.circom";
|
||||
template Sha224HashChunks(BLOCK_NUM) {
|
||||
|
||||
signal input in[BLOCK_NUM * 512];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[224];
|
||||
|
||||
signal states[BLOCK_NUM + 1][8][32];
|
||||
@@ -23,9 +21,7 @@ template Sha224HashChunks(BLOCK_NUM) {
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
|
||||
sch[m] = Sha2_224_256Shedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_224_256Rounds(64);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 32; i++) {
|
||||
|
||||
@@ -12,8 +12,6 @@ template Sha2_224_256CompressInner() {
|
||||
|
||||
signal input inp;
|
||||
signal input key;
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal input a[32];
|
||||
signal input b[32];
|
||||
@@ -39,9 +37,7 @@ template Sha2_224_256CompressInner() {
|
||||
outB <== a;
|
||||
|
||||
component dSum = GetSumOfNElements(32);
|
||||
dSum.dummy <== dummy;
|
||||
component hSum = GetSumOfNElements(32);
|
||||
hSum.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 32; i++) {
|
||||
dSum.in[i] <== (1 << i) * c[i];
|
||||
@@ -57,13 +53,9 @@ template Sha2_224_256CompressInner() {
|
||||
component s1Xor[32];
|
||||
|
||||
component s0Sum = GetSumOfNElements(32);
|
||||
s0Sum.dummy <== dummy;
|
||||
component s1Sum = GetSumOfNElements(32);
|
||||
s1Sum.dummy <== dummy;
|
||||
component mjSum = GetSumOfNElements(32);
|
||||
mjSum.dummy <== dummy;
|
||||
component chSum = GetSumOfNElements(32);
|
||||
chSum.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 32; i++) {
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ include "sha256Rounds.circom";
|
||||
template Sha256HashBits(LEN) {
|
||||
|
||||
signal input in[LEN];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[256];
|
||||
|
||||
@@ -29,9 +27,7 @@ template Sha256HashBits(LEN) {
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
|
||||
sch[m] = Sha2_224_256Shedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_224_256Rounds(64);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 32; i++) {
|
||||
|
||||
@@ -8,12 +8,9 @@ include "sha256Rounds.circom";
|
||||
template Sha256HashChunks(BLOCK_NUM) {
|
||||
|
||||
signal input in[BLOCK_NUM * 512];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[256];
|
||||
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal states[BLOCK_NUM + 1][8][32];
|
||||
|
||||
@@ -26,9 +23,7 @@ template Sha256HashChunks(BLOCK_NUM) {
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
|
||||
sch[m] = Sha2_224_256Shedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_224_256Rounds(64);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 32; i++) {
|
||||
|
||||
@@ -18,8 +18,6 @@ template Sha2_224_256Rounds(n) {
|
||||
signal input inpHash[8][32];
|
||||
signal output outHash[8][32];
|
||||
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal a [n + 1][32];
|
||||
signal b [n + 1][32];
|
||||
@@ -43,9 +41,7 @@ template Sha2_224_256Rounds(n) {
|
||||
g[0] <== inpHash[6];
|
||||
|
||||
component sumDd = GetSumOfNElements(32);
|
||||
sumDd.dummy <== dummy;
|
||||
component sumHh = GetSumOfNElements(32);
|
||||
sumHh.dummy <== dummy;
|
||||
for (var i = 0; i < 32; i++) {
|
||||
sumDd.in[i] <== inpHash[3][i] * (1 << i);
|
||||
sumHh.in[i] <== inpHash[7][i] * (1 << i);
|
||||
@@ -57,7 +53,6 @@ template Sha2_224_256Rounds(n) {
|
||||
component sum[8];
|
||||
for (var j = 0; j < 8; j++) {
|
||||
sum[j] = GetSumOfNElements(32);
|
||||
sum[j].dummy <== dummy;
|
||||
for (var i = 0; i < 32; i++) {
|
||||
sum[j].in[i] <== (1 << i) * inpHash[j][i];
|
||||
}
|
||||
@@ -72,7 +67,6 @@ template Sha2_224_256Rounds(n) {
|
||||
|
||||
compress[k].inp <== words[k];
|
||||
compress[k].key <== ROUND_KEYS[k];
|
||||
compress[k].dummy <== dummy;
|
||||
|
||||
compress[k].a <== a [k];
|
||||
compress[k].b <== b [k];
|
||||
@@ -98,17 +92,11 @@ template Sha2_224_256Rounds(n) {
|
||||
modulo[j] = GetLastNBits(32);
|
||||
}
|
||||
component sumA = GetSumOfNElements(32);
|
||||
sumA.dummy <== dummy;
|
||||
component sumB = GetSumOfNElements(32);
|
||||
sumB.dummy <== dummy;
|
||||
component sumC = GetSumOfNElements(32);
|
||||
sumC.dummy <== dummy;
|
||||
component sumE = GetSumOfNElements(32);
|
||||
sumE.dummy <== dummy;
|
||||
component sumF = GetSumOfNElements(32);
|
||||
sumF.dummy <== dummy;
|
||||
component sumG = GetSumOfNElements(32);
|
||||
sumG.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 32; i++) {
|
||||
sumA.in[i] <== (1 << i) * a[n][i];
|
||||
@@ -119,14 +107,14 @@ template Sha2_224_256Rounds(n) {
|
||||
sumG.in[i] <== (1 << i) * g[n][i];
|
||||
}
|
||||
|
||||
modulo[0].in <== hashWords[0] + sumA.out + dummy * dummy;
|
||||
modulo[1].in <== hashWords[1] + sumB.out + dummy * dummy;
|
||||
modulo[2].in <== hashWords[2] + sumC.out + dummy * dummy;
|
||||
modulo[3].in <== hashWords[3] + dd[n] + dummy * dummy;
|
||||
modulo[4].in <== hashWords[4] + sumE.out + dummy * dummy;
|
||||
modulo[5].in <== hashWords[5] + sumF.out + dummy * dummy;
|
||||
modulo[6].in <== hashWords[6] + sumG.out + dummy * dummy;
|
||||
modulo[7].in <== hashWords[7] + hh[n] + dummy * dummy;
|
||||
modulo[0].in <== hashWords[0] + sumA.out;
|
||||
modulo[1].in <== hashWords[1] + sumB.out;
|
||||
modulo[2].in <== hashWords[2] + sumC.out;
|
||||
modulo[3].in <== hashWords[3] + dd[n];
|
||||
modulo[4].in <== hashWords[4] + sumE.out;
|
||||
modulo[5].in <== hashWords[5] + sumF.out;
|
||||
modulo[6].in <== hashWords[6] + sumG.out;
|
||||
modulo[7].in <== hashWords[7] + hh[n];
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
modulo[j].out ==> outHash[j];
|
||||
|
||||
@@ -13,15 +13,12 @@ template Sha2_224_256Shedule() {
|
||||
signal input chunkBits[16][32];
|
||||
signal output outWords [64];
|
||||
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal outBits[64][32];
|
||||
|
||||
component sumN[16];
|
||||
for (var k = 0; k < 16; k++) {
|
||||
sumN[k] = GetSumOfNElements(32);
|
||||
sumN[k].dummy <== dummy;
|
||||
for (var i = 0; i < 32; i++) {
|
||||
sumN[k].in[i] <== (1 << i) * chunkBits[k][i];
|
||||
}
|
||||
@@ -43,9 +40,7 @@ template Sha2_224_256Shedule() {
|
||||
var l = m - 2;
|
||||
|
||||
s0Sum[m - 16] = GetSumOfNElements(32);
|
||||
s0Sum[m - 16].dummy <== dummy;
|
||||
s1Sum[m - 16] = GetSumOfNElements(32);
|
||||
s1Sum[m - 16].dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 32; i++) {
|
||||
|
||||
@@ -68,7 +63,7 @@ template Sha2_224_256Shedule() {
|
||||
|
||||
|
||||
modulo[r] = GetLastNBits(32);
|
||||
modulo[r].in <== s1Sum[m - 16].out + outWords[m - 7] + s0Sum[m - 16].out + outWords[m - 16] + dummy * dummy;
|
||||
modulo[r].in <== s1Sum[m - 16].out + outWords[m - 7] + s0Sum[m - 16].out + outWords[m - 16];
|
||||
modulo[r].out ==> outBits[m];
|
||||
bits2Num[r] = Bits2Num(32);
|
||||
bits2Num[r].in <== outBits[m];
|
||||
|
||||
@@ -1,101 +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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Binary Sum
|
||||
==========
|
||||
|
||||
This component creates a binary sum componet of ops operands and n bits each operand.
|
||||
|
||||
e is Number of carries: Depends on the number of operands in the input.
|
||||
|
||||
Main Constraint:
|
||||
in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) +
|
||||
+ in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) +
|
||||
+ ..
|
||||
+ in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) +
|
||||
===
|
||||
out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1)
|
||||
|
||||
To waranty binary outputs:
|
||||
|
||||
out[0] * (out[0] - 1) === 0
|
||||
out[1] * (out[0] - 1) === 0
|
||||
.
|
||||
.
|
||||
.
|
||||
out[n+e-1] * (out[n+e-1] - 1) == 0
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
This function calculates the number of extra bits in the output to do the full sum.
|
||||
*/
|
||||
pragma circom 2.0.0;
|
||||
|
||||
function nbits(a) {
|
||||
var n = 1;
|
||||
var r = 0;
|
||||
while (n-1<a) {
|
||||
r++;
|
||||
n *= 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
template BinSum_circomlib(n, ops) {
|
||||
var nout = nbits((2**n -1)*ops);
|
||||
signal input in[ops][n];
|
||||
signal output out[nout];
|
||||
|
||||
var lin = 0;
|
||||
var lout = 0;
|
||||
|
||||
var k;
|
||||
var j;
|
||||
|
||||
var e2;
|
||||
|
||||
e2 = 1;
|
||||
for (k=0; k<n; k++) {
|
||||
for (j=0; j<ops; j++) {
|
||||
lin += in[j][k] * e2;
|
||||
}
|
||||
e2 = e2 + e2;
|
||||
}
|
||||
|
||||
e2 = 1;
|
||||
for (k=0; k<nout; k++) {
|
||||
out[k] <-- (lin >> k) & 1;
|
||||
|
||||
// Ensure out is binary
|
||||
out[k] * (out[k] - 1) === 0;
|
||||
|
||||
lout += out[k] * e2;
|
||||
|
||||
e2 = e2+e2;
|
||||
}
|
||||
|
||||
// Ensure the sum;
|
||||
|
||||
lin === lout;
|
||||
}
|
||||
@@ -1,53 +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;
|
||||
|
||||
template H_sha256(x) {
|
||||
signal output out[32];
|
||||
var c[8] = [0x6a09e667,
|
||||
0xbb67ae85,
|
||||
0x3c6ef372,
|
||||
0xa54ff53a,
|
||||
0x510e527f,
|
||||
0x9b05688c,
|
||||
0x1f83d9ab,
|
||||
0x5be0cd19];
|
||||
|
||||
for (var i=0; i<32; i++) {
|
||||
out[i] <== (c[x] >> i) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
template K_sha256(x) {
|
||||
signal output out[32];
|
||||
var c[64] = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
];
|
||||
|
||||
for (var i=0; i<32; i++) {
|
||||
out[i] <== (c[x] >> i) & 1;
|
||||
}
|
||||
}
|
||||
@@ -1,45 +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/>.
|
||||
*/
|
||||
|
||||
/* Maj function for sha256
|
||||
|
||||
out = a&b ^ a&c ^ b&c =>
|
||||
|
||||
out = a*b + a*c + b*c - 2*a*b*c =>
|
||||
|
||||
out = a*( b + c - 2*b*c ) + b*c =>
|
||||
|
||||
mid = b*c
|
||||
out = a*( b + c - 2*mid ) + mid
|
||||
|
||||
*/
|
||||
pragma circom 2.0.0;
|
||||
|
||||
template Maj_t(n) {
|
||||
signal input a[n];
|
||||
signal input b[n];
|
||||
signal input c[n];
|
||||
signal output out[n];
|
||||
signal mid[n];
|
||||
|
||||
for (var k=0; k<n; k++) {
|
||||
mid[k] <== b[k]*c[k];
|
||||
out[k] <== a[k] * (b[k]+c[k]-2*mid[k]) + mid[k];
|
||||
}
|
||||
}
|
||||
@@ -1,28 +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;
|
||||
|
||||
template RotR(n, r) {
|
||||
signal input in[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
out[i] <== in[ (i+r)%n ];
|
||||
}
|
||||
}
|
||||
@@ -1,166 +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 "constants.circom";
|
||||
include "t1.circom";
|
||||
include "t2.circom";
|
||||
include "./binsum.circom";
|
||||
include "sigmaplus.circom";
|
||||
include "sha256compression_function.circom";
|
||||
|
||||
|
||||
template Sha256compression() {
|
||||
signal input hin[256];
|
||||
signal input inp[512];
|
||||
signal output out[256];
|
||||
signal a[65][32];
|
||||
signal b[65][32];
|
||||
signal c[65][32];
|
||||
signal d[65][32];
|
||||
signal e[65][32];
|
||||
signal f[65][32];
|
||||
signal g[65][32];
|
||||
signal h[65][32];
|
||||
signal w[64][32];
|
||||
|
||||
|
||||
var outCalc[256] = sha256compression(hin, inp);
|
||||
|
||||
var i;
|
||||
for (i=0; i<256; i++) out[i] <-- outCalc[i];
|
||||
|
||||
component sigmaPlus[48];
|
||||
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
|
||||
|
||||
component ct_k[64];
|
||||
for (i=0; i<64; i++) ct_k[i] = K_sha256(i);
|
||||
|
||||
component t1[64];
|
||||
for (i=0; i<64; i++) t1[i] = T1();
|
||||
|
||||
component t2[64];
|
||||
for (i=0; i<64; i++) t2[i] = T2();
|
||||
|
||||
component suma[64];
|
||||
for (i=0; i<64; i++) suma[i] = BinSum_circomlib(32, 2);
|
||||
|
||||
component sume[64];
|
||||
for (i=0; i<64; i++) sume[i] = BinSum_circomlib(32, 2);
|
||||
|
||||
component fsum[8];
|
||||
for (i=0; i<8; i++) fsum[i] = BinSum_circomlib(32, 2);
|
||||
|
||||
var k;
|
||||
var t;
|
||||
|
||||
for (t=0; t<64; t++) {
|
||||
if (t<16) {
|
||||
for (k=0; k<32; k++) {
|
||||
w[t][k] <== inp[t*32+31-k];
|
||||
}
|
||||
} else {
|
||||
for (k=0; k<32; k++) {
|
||||
sigmaPlus[t-16].in2[k] <== w[t-2][k];
|
||||
sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
||||
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
||||
sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
w[t][k] <== sigmaPlus[t-16].out[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++ ) {
|
||||
a[0][k] <== hin[k];
|
||||
b[0][k] <== hin[32*1 + k];
|
||||
c[0][k] <== hin[32*2 + k];
|
||||
d[0][k] <== hin[32*3 + k];
|
||||
e[0][k] <== hin[32*4 + k];
|
||||
f[0][k] <== hin[32*5 + k];
|
||||
g[0][k] <== hin[32*6 + k];
|
||||
h[0][k] <== hin[32*7 + k];
|
||||
}
|
||||
|
||||
for (t = 0; t<64; t++) {
|
||||
for (k=0; k<32; k++) {
|
||||
t1[t].h[k] <== h[t][k];
|
||||
t1[t].e[k] <== e[t][k];
|
||||
t1[t].f[k] <== f[t][k];
|
||||
t1[t].g[k] <== g[t][k];
|
||||
t1[t].k[k] <== ct_k[t].out[k];
|
||||
t1[t].w[k] <== w[t][k];
|
||||
|
||||
t2[t].a[k] <== a[t][k];
|
||||
t2[t].b[k] <== b[t][k];
|
||||
t2[t].c[k] <== c[t][k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
sume[t].in[0][k] <== d[t][k];
|
||||
sume[t].in[1][k] <== t1[t].out[k];
|
||||
|
||||
suma[t].in[0][k] <== t1[t].out[k];
|
||||
suma[t].in[1][k] <== t2[t].out[k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
h[t+1][k] <== g[t][k];
|
||||
g[t+1][k] <== f[t][k];
|
||||
f[t+1][k] <== e[t][k];
|
||||
e[t+1][k] <== sume[t].out[k];
|
||||
d[t+1][k] <== c[t][k];
|
||||
c[t+1][k] <== b[t][k];
|
||||
b[t+1][k] <== a[t][k];
|
||||
a[t+1][k] <== suma[t].out[k];
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
fsum[0].in[0][k] <== hin[32*0+k];
|
||||
fsum[0].in[1][k] <== a[64][k];
|
||||
fsum[1].in[0][k] <== hin[32*1+k];
|
||||
fsum[1].in[1][k] <== b[64][k];
|
||||
fsum[2].in[0][k] <== hin[32*2+k];
|
||||
fsum[2].in[1][k] <== c[64][k];
|
||||
fsum[3].in[0][k] <== hin[32*3+k];
|
||||
fsum[3].in[1][k] <== d[64][k];
|
||||
fsum[4].in[0][k] <== hin[32*4+k];
|
||||
fsum[4].in[1][k] <== e[64][k];
|
||||
fsum[5].in[0][k] <== hin[32*5+k];
|
||||
fsum[5].in[1][k] <== f[64][k];
|
||||
fsum[6].in[0][k] <== hin[32*6+k];
|
||||
fsum[6].in[1][k] <== g[64][k];
|
||||
fsum[7].in[0][k] <== hin[32*7+k];
|
||||
fsum[7].in[1][k] <== h[64][k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
out[31-k] === fsum[0].out[k];
|
||||
out[32+31-k] === fsum[1].out[k];
|
||||
out[64+31-k] === fsum[2].out[k];
|
||||
out[96+31-k] === fsum[3].out[k];
|
||||
out[128+31-k] === fsum[4].out[k];
|
||||
out[160+31-k] === fsum[5].out[k];
|
||||
out[192+31-k] === fsum[6].out[k];
|
||||
out[224+31-k] === fsum[7].out[k];
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
// signal input hin[256];
|
||||
// signal input inp[512];
|
||||
// signal output out[256];
|
||||
pragma circom 2.0.0;
|
||||
|
||||
function rrot(x, n) {
|
||||
return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
function bsigma0(x) {
|
||||
return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22);
|
||||
}
|
||||
|
||||
function bsigma1(x) {
|
||||
return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25);
|
||||
}
|
||||
|
||||
function ssigma0(x) {
|
||||
return rrot(x,7) ^ rrot(x,18) ^ (x >> 3);
|
||||
}
|
||||
|
||||
function ssigma1(x) {
|
||||
return rrot(x,17) ^ rrot(x,19) ^ (x >> 10);
|
||||
}
|
||||
|
||||
function Maj(x, y, z) {
|
||||
return (x&y) ^ (x&z) ^ (y&z);
|
||||
}
|
||||
|
||||
function Ch(x, y, z) {
|
||||
return (x & y) ^ ((0xFFFFFFFF ^x) & z);
|
||||
}
|
||||
|
||||
function sha256K(i) {
|
||||
var k[64] = [
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||
];
|
||||
return k[i];
|
||||
}
|
||||
|
||||
function sha256compression(hin, inp) {
|
||||
var H[8];
|
||||
var a;
|
||||
var b;
|
||||
var c;
|
||||
var d;
|
||||
var e;
|
||||
var f;
|
||||
var g;
|
||||
var h;
|
||||
var out[256];
|
||||
for (var i=0; i<8; i++) {
|
||||
H[i] = 0;
|
||||
for (var j=0; j<32; j++) {
|
||||
H[i] += hin[i*32+j] << j;
|
||||
}
|
||||
}
|
||||
a=H[0];
|
||||
b=H[1];
|
||||
c=H[2];
|
||||
d=H[3];
|
||||
e=H[4];
|
||||
f=H[5];
|
||||
g=H[6];
|
||||
h=H[7];
|
||||
var w[64];
|
||||
var T1;
|
||||
var T2;
|
||||
for (var i=0; i<64; i++) {
|
||||
if (i<16) {
|
||||
w[i]=0;
|
||||
for (var j=0; j<32; j++) {
|
||||
w[i] += inp[i*32+31-j]<<j;
|
||||
}
|
||||
} else {
|
||||
w[i] = (ssigma1(w[i-2]) + w[i-7] + ssigma0(w[i-15]) + w[i-16]) & 0xFFFFFFFF;
|
||||
}
|
||||
T1 = (h + bsigma1(e) + Ch(e,f,g) + sha256K(i) + w[i]) & 0xFFFFFFFF;
|
||||
T2 = (bsigma0(a) + Maj(a,b,c)) & 0xFFFFFFFF;
|
||||
|
||||
h=g;
|
||||
g=f;
|
||||
f=e;
|
||||
e=(d+T1) & 0xFFFFFFFF;
|
||||
d=c;
|
||||
c=b;
|
||||
b=a;
|
||||
a=(T1+T2) & 0xFFFFFFFF;
|
||||
|
||||
}
|
||||
H[0] = H[0] + a;
|
||||
H[1] = H[1] + b;
|
||||
H[2] = H[2] + c;
|
||||
H[3] = H[3] + d;
|
||||
H[4] = H[4] + e;
|
||||
H[5] = H[5] + f;
|
||||
H[6] = H[6] + g;
|
||||
H[7] = H[7] + h;
|
||||
for (var i=0; i<8; i++) {
|
||||
for (var j=0; j<32; j++) {
|
||||
out[i*32+31-j] = (H[i] >> j) & 1;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -1,33 +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;
|
||||
|
||||
template ShR(n, r) {
|
||||
signal input in[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
if (i+r >= n) {
|
||||
out[i] <== 0;
|
||||
} else {
|
||||
out[i] <== in[ i+r ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +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 "xor3.circom";
|
||||
include "rotate.circom";
|
||||
include "shift.circom";
|
||||
|
||||
template SmallSigma(ra, rb, rc) {
|
||||
signal input in[32];
|
||||
signal output out[32];
|
||||
var k;
|
||||
|
||||
component rota = RotR(32, ra);
|
||||
component rotb = RotR(32, rb);
|
||||
component shrc = ShR(32, rc);
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
rota.in[k] <== in[k];
|
||||
rotb.in[k] <== in[k];
|
||||
shrc.in[k] <== in[k];
|
||||
}
|
||||
|
||||
component xor3 = Xor3(32);
|
||||
for (k=0; k<32; k++) {
|
||||
xor3.a[k] <== rota.out[k];
|
||||
xor3.b[k] <== rotb.out[k];
|
||||
xor3.c[k] <== shrc.out[k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
out[k] <== xor3.out[k];
|
||||
}
|
||||
}
|
||||
|
||||
template BigSigma(ra, rb, rc) {
|
||||
signal input in[32];
|
||||
signal output out[32];
|
||||
var k;
|
||||
|
||||
component rota = RotR(32, ra);
|
||||
component rotb = RotR(32, rb);
|
||||
component rotc = RotR(32, rc);
|
||||
for (k=0; k<32; k++) {
|
||||
rota.in[k] <== in[k];
|
||||
rotb.in[k] <== in[k];
|
||||
rotc.in[k] <== in[k];
|
||||
}
|
||||
|
||||
component xor3 = Xor3(32);
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
xor3.a[k] <== rota.out[k];
|
||||
xor3.b[k] <== rotb.out[k];
|
||||
xor3.c[k] <== rotc.out[k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
out[k] <== xor3.out[k];
|
||||
}
|
||||
}
|
||||
@@ -1,50 +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 "./binsum.circom";
|
||||
include "sigma.circom";
|
||||
|
||||
template SigmaPlus() {
|
||||
signal input in2[32];
|
||||
signal input in7[32];
|
||||
signal input in15[32];
|
||||
signal input in16[32];
|
||||
signal output out[32];
|
||||
var k;
|
||||
|
||||
component sigma1 = SmallSigma(17,19,10);
|
||||
component sigma0 = SmallSigma(7, 18, 3);
|
||||
for (k=0; k<32; k++) {
|
||||
sigma1.in[k] <== in2[k];
|
||||
sigma0.in[k] <== in15[k];
|
||||
}
|
||||
|
||||
component sum = BinSum_circomlib(32, 4);
|
||||
for (k=0; k<32; k++) {
|
||||
sum.in[0][k] <== sigma1.out[k];
|
||||
sum.in[1][k] <== in7[k];
|
||||
sum.in[2][k] <== sigma0.out[k];
|
||||
sum.in[3][k] <== in16[k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
out[k] <== sum.out[k];
|
||||
}
|
||||
}
|
||||
@@ -1,58 +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 "./binsum.circom";
|
||||
include "sigma.circom";
|
||||
include "ch.circom";
|
||||
|
||||
template T1() {
|
||||
signal input h[32];
|
||||
signal input e[32];
|
||||
signal input f[32];
|
||||
signal input g[32];
|
||||
signal input k[32];
|
||||
signal input w[32];
|
||||
signal output out[32];
|
||||
|
||||
var ki;
|
||||
|
||||
component ch = Ch_t(32);
|
||||
component bigsigma1 = BigSigma(6, 11, 25);
|
||||
|
||||
for (ki=0; ki<32; ki++) {
|
||||
bigsigma1.in[ki] <== e[ki];
|
||||
ch.a[ki] <== e[ki];
|
||||
ch.b[ki] <== f[ki];
|
||||
ch.c[ki] <== g[ki];
|
||||
}
|
||||
|
||||
component sum = BinSum_circomlib(32, 5);
|
||||
for (ki=0; ki<32; ki++) {
|
||||
sum.in[0][ki] <== h[ki];
|
||||
sum.in[1][ki] <== bigsigma1.out[ki];
|
||||
sum.in[2][ki] <== ch.out[ki];
|
||||
sum.in[3][ki] <== k[ki];
|
||||
sum.in[4][ki] <== w[ki];
|
||||
}
|
||||
|
||||
for (ki=0; ki<32; ki++) {
|
||||
out[ki] <== sum.out[ki];
|
||||
}
|
||||
}
|
||||
@@ -1,51 +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 "./binsum.circom";
|
||||
include "sigma.circom";
|
||||
include "maj.circom";
|
||||
|
||||
template T2() {
|
||||
signal input a[32];
|
||||
signal input b[32];
|
||||
signal input c[32];
|
||||
signal output out[32];
|
||||
var k;
|
||||
|
||||
component bigsigma0 = BigSigma(2, 13, 22);
|
||||
component maj = Maj_t(32);
|
||||
for (k=0; k<32; k++) {
|
||||
bigsigma0.in[k] <== a[k];
|
||||
maj.a[k] <== a[k];
|
||||
maj.b[k] <== b[k];
|
||||
maj.c[k] <== c[k];
|
||||
}
|
||||
|
||||
component sum = BinSum_circomlib(32, 2);
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
sum.in[0][k] <== bigsigma0.out[k];
|
||||
sum.in[1][k] <== maj.out[k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
out[k] <== sum.out[k];
|
||||
}
|
||||
}
|
||||
@@ -1,45 +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/>.
|
||||
*/
|
||||
|
||||
/* Xor3 function for sha256
|
||||
|
||||
out = a ^ b ^ c =>
|
||||
|
||||
out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c =>
|
||||
|
||||
out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c =>
|
||||
|
||||
mid = b*c
|
||||
out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid
|
||||
|
||||
*/
|
||||
pragma circom 2.0.0;
|
||||
|
||||
template Xor3(n) {
|
||||
signal input a[n];
|
||||
signal input b[n];
|
||||
signal input c[n];
|
||||
signal output out[n];
|
||||
signal mid[n];
|
||||
|
||||
for (var k=0; k<n; k++) {
|
||||
mid[k] <== b[k]*c[k];
|
||||
out[k] <== a[k] * (1 -2*b[k] -2*c[k] +4*mid[k]) + b[k] + c[k] -2*mid[k];
|
||||
}
|
||||
}
|
||||
@@ -68,25 +68,11 @@ template Bits2() {
|
||||
xy === 2 * hi + lo;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// XOR 3 bits together
|
||||
|
||||
template XOR3_v1() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
signal input z;
|
||||
signal output out;
|
||||
|
||||
component bs = Bits2();
|
||||
bs.xy <== x + y + z;
|
||||
bs.lo ==> out;
|
||||
}
|
||||
|
||||
//------------------
|
||||
// same number of constraints (that is, 2), in the general case
|
||||
// however circom can optimize y=0 or z=0, unlike with the above
|
||||
// and hopefully also x=0.
|
||||
|
||||
// used in sha256 and sha512
|
||||
template XOR3_v2() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
@@ -98,7 +84,7 @@ template XOR3_v2() {
|
||||
}
|
||||
|
||||
// for many xors use this one
|
||||
|
||||
// used in sha1
|
||||
template XOR3_v3(n) {
|
||||
signal input a[n];
|
||||
signal input b[n];
|
||||
|
||||
@@ -8,8 +8,6 @@ include "sha384InitialValue.circom";
|
||||
template Sha384HashBits(LEN) {
|
||||
|
||||
signal input in[LEN];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out[384];
|
||||
|
||||
component addPadding = ShaPadding(LEN, 1024);
|
||||
@@ -28,9 +26,7 @@ template Sha384HashBits(LEN) {
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
|
||||
sch[m] = Sha2_384_512Schedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_384_512Rounds(80);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 64; i++) {
|
||||
|
||||
@@ -7,7 +7,6 @@ include "../../../utils/array.circom";
|
||||
include "sha384InitialValue.circom";
|
||||
|
||||
template Sha384HashChunks(MAX_BLOCKS) {
|
||||
|
||||
signal input in[MAX_BLOCKS * 1024];
|
||||
signal input paddedInLength;
|
||||
signal input dummy;
|
||||
@@ -31,9 +30,7 @@ template Sha384HashChunks(MAX_BLOCKS) {
|
||||
for (var m = 0; m < MAX_BLOCKS; m++) {
|
||||
|
||||
sch[m] = Sha2_384_512Schedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_384_512Rounds(80);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 64; i++) {
|
||||
|
||||
@@ -12,8 +12,6 @@ template Sha2_384_512CompressInner() {
|
||||
|
||||
signal input inp;
|
||||
signal input key;
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal input a[64];
|
||||
signal input b[64];
|
||||
@@ -34,9 +32,7 @@ template Sha2_384_512CompressInner() {
|
||||
signal output outHH;
|
||||
|
||||
component dSum = GetSumOfNElements(64);
|
||||
dSum.dummy <== dummy;
|
||||
component hSum = GetSumOfNElements(64);
|
||||
hSum.dummy <== dummy;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
outG[i] <== f[i];
|
||||
outF[i] <== e[i];
|
||||
@@ -55,13 +51,9 @@ template Sha2_384_512CompressInner() {
|
||||
component s1Xor[64];
|
||||
|
||||
component s0Sum = GetSumOfNElements(64);
|
||||
s0Sum.dummy <== dummy;
|
||||
component s1Sum = GetSumOfNElements(64);
|
||||
s1Sum.dummy <== dummy;
|
||||
component mjSum = GetSumOfNElements(64);
|
||||
mjSum.dummy <== dummy;
|
||||
component chSum = GetSumOfNElements(64);
|
||||
chSum.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 64; i++) {
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ include "sha512Rounds.circom";
|
||||
template Sha512HashBits(LEN) {
|
||||
|
||||
signal input in[LEN];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal output out[512];
|
||||
|
||||
@@ -29,9 +27,7 @@ template Sha512HashBits(LEN) {
|
||||
for (var m = 0; m < BLOCK_NUM; m++) {
|
||||
|
||||
sch[m] = Sha2_384_512Schedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_384_512Rounds(80);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 64; i++) {
|
||||
|
||||
@@ -7,7 +7,6 @@ include "../../../utils/array.circom";
|
||||
include "sha512Rounds.circom";
|
||||
|
||||
template Sha512HashChunks(MAX_BLOCKS) {
|
||||
|
||||
signal input in[MAX_BLOCKS * 1024];
|
||||
signal input paddedInLength;
|
||||
signal input dummy;
|
||||
@@ -31,9 +30,7 @@ template Sha512HashChunks(MAX_BLOCKS) {
|
||||
for (var m = 0; m < MAX_BLOCKS; m++) {
|
||||
|
||||
sch[m] = Sha2_384_512Schedule();
|
||||
sch[m].dummy <== dummy;
|
||||
rds[m] = Sha2_384_512Rounds(80);
|
||||
rds[m].dummy <== dummy;
|
||||
|
||||
for (var k = 0; k < 16; k++) {
|
||||
for (var i = 0; i < 64; i++) {
|
||||
|
||||
@@ -17,8 +17,6 @@ template Sha2_384_512Rounds(n) {
|
||||
signal input inpHash[8][64];
|
||||
signal output outHash[8][64];
|
||||
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal a [n + 1][64];
|
||||
signal b [n + 1][64];
|
||||
@@ -42,9 +40,7 @@ template Sha2_384_512Rounds(n) {
|
||||
g[0] <== inpHash[6];
|
||||
|
||||
component sumDd = GetSumOfNElements(64);
|
||||
sumDd.dummy <== dummy;
|
||||
component sumHh = GetSumOfNElements(64);
|
||||
sumHh.dummy <== dummy;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
sumDd.in[i] <== inpHash[3][i] * (1 << i);
|
||||
sumHh.in[i] <== inpHash[7][i] * (1 << i);
|
||||
@@ -56,7 +52,6 @@ template Sha2_384_512Rounds(n) {
|
||||
component sum[8];
|
||||
for (var j = 0; j < 8; j++) {
|
||||
sum[j] = GetSumOfNElements(64);
|
||||
sum[j].dummy <== dummy;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
sum[j].in[i] <== (1 << i) * inpHash[j][i];
|
||||
}
|
||||
@@ -71,7 +66,6 @@ template Sha2_384_512Rounds(n) {
|
||||
|
||||
compress[k].inp <== words[k];
|
||||
compress[k].key <== ROUND_KEYS[k];
|
||||
compress[k].dummy <== dummy;
|
||||
|
||||
|
||||
compress[k].a <== a [k];
|
||||
@@ -99,17 +93,11 @@ template Sha2_384_512Rounds(n) {
|
||||
}
|
||||
|
||||
component sumA = GetSumOfNElements(64);
|
||||
sumA.dummy <== dummy;
|
||||
component sumB = GetSumOfNElements(64);
|
||||
sumB.dummy <== dummy;
|
||||
component sumC = GetSumOfNElements(64);
|
||||
sumC.dummy <== dummy;
|
||||
component sumE = GetSumOfNElements(64);
|
||||
sumE.dummy <== dummy;
|
||||
component sumF = GetSumOfNElements(64);
|
||||
sumF.dummy <== dummy;
|
||||
component sumG = GetSumOfNElements(64);
|
||||
sumG.dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 64; i++) {
|
||||
sumA.in[i] <== (1 << i) * a[n][i];
|
||||
@@ -120,14 +108,14 @@ template Sha2_384_512Rounds(n) {
|
||||
sumG.in[i] <== (1 << i) * g[n][i];
|
||||
}
|
||||
|
||||
modulo[0].in <== hashWords[0] + sumA.out + dummy * dummy;
|
||||
modulo[1].in <== hashWords[1] + sumB.out + dummy * dummy;
|
||||
modulo[2].in <== hashWords[2] + sumC.out + dummy * dummy;
|
||||
modulo[3].in <== hashWords[3] + dd[n] + dummy * dummy;
|
||||
modulo[4].in <== hashWords[4] + sumE.out + dummy * dummy;
|
||||
modulo[5].in <== hashWords[5] + sumF.out + dummy * dummy;
|
||||
modulo[6].in <== hashWords[6] + sumG.out + dummy * dummy;
|
||||
modulo[7].in <== hashWords[7] + hh[n] + dummy * dummy;
|
||||
modulo[0].in <== hashWords[0] + sumA.out;
|
||||
modulo[1].in <== hashWords[1] + sumB.out;
|
||||
modulo[2].in <== hashWords[2] + sumC.out;
|
||||
modulo[3].in <== hashWords[3] + dd[n];
|
||||
modulo[4].in <== hashWords[4] + sumE.out;
|
||||
modulo[5].in <== hashWords[5] + sumF.out;
|
||||
modulo[6].in <== hashWords[6] + sumG.out;
|
||||
modulo[7].in <== hashWords[7] + hh[n];
|
||||
|
||||
for (var j = 0; j < 8; j++) {
|
||||
modulo[j].out ==> outHash[j];
|
||||
|
||||
@@ -12,8 +12,6 @@ template Sha2_384_512Schedule() {
|
||||
|
||||
signal input chunkBits[16][64];
|
||||
signal output outWords [80];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
|
||||
signal outBits[80][64];
|
||||
|
||||
@@ -21,7 +19,6 @@ template Sha2_384_512Schedule() {
|
||||
component sumN[16];
|
||||
for (var k = 0; k < 16; k++) {
|
||||
sumN[k] = GetSumOfNElements(64);
|
||||
sumN[k].dummy <== dummy;
|
||||
for (var i = 0; i < 64; i++) {
|
||||
sumN[k].in[i] <== (1 << i) * chunkBits[k][i];
|
||||
}
|
||||
@@ -44,9 +41,7 @@ template Sha2_384_512Schedule() {
|
||||
var l = m - 2;
|
||||
|
||||
s0Sum[m - 16] = GetSumOfNElements(64);
|
||||
s0Sum[m - 16].dummy <== dummy;
|
||||
s1Sum[m - 16] = GetSumOfNElements(64);
|
||||
s1Sum[m - 16].dummy <== dummy;
|
||||
|
||||
for (var i = 0; i < 64; i++) {
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ pragma circom 2.1.5;
|
||||
|
||||
include "../../sha1/sha1compression.circom";
|
||||
include "../../sha1/constants.circom";
|
||||
include "../../../bitify/bitify.circom";
|
||||
include "../../../utils/array.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
//Adapted from @zk-email/circuits/helpers/sha.circom
|
||||
template Sha1Bytes(max_num_bytes) {
|
||||
@@ -36,7 +36,7 @@ template Sha1Bytes(max_num_bytes) {
|
||||
template Sha1General(maxBitsPadded) {
|
||||
assert(maxBitsPadded % 512 == 0);
|
||||
var maxBitsPaddedBits = log2Ceil(maxBitsPadded);
|
||||
assert(2 ** maxBitsPaddedBits > maxBitsPadded);
|
||||
assert(2 ** maxBitsPaddedBits >= maxBitsPadded);
|
||||
|
||||
signal input paddedIn[maxBitsPadded];
|
||||
signal output out[160];
|
||||
@@ -49,7 +49,7 @@ template Sha1General(maxBitsPadded) {
|
||||
var maxBlocks;
|
||||
maxBlocks = (maxBitsPadded\512);
|
||||
var maxBlocksBits = log2Ceil(maxBlocks);
|
||||
assert(2 ** maxBlocksBits > maxBlocks);
|
||||
assert(2 ** maxBlocksBits >= maxBlocks);
|
||||
|
||||
inBlockIndex <-- (in_len_padded_bits >> 9);
|
||||
in_len_padded_bits === inBlockIndex * 512;
|
||||
@@ -59,18 +59,17 @@ template Sha1General(maxBitsPadded) {
|
||||
bitLengthVerifier.in[1] <== maxBitsPadded;
|
||||
bitLengthVerifier.out === 1;
|
||||
|
||||
component ha0 = H(0);
|
||||
component hb0 = H(1);
|
||||
component hc0 = H(2);
|
||||
component hd0 = H(3);
|
||||
component he0 = H(4);
|
||||
component ha0 = H_sha1(0);
|
||||
component hb0 = H_sha1(1);
|
||||
component hc0 = H_sha1(2);
|
||||
component hd0 = H_sha1(3);
|
||||
component he0 = H_sha1(4);
|
||||
|
||||
component sha1compression[maxBlocks];
|
||||
|
||||
for (i=0; i<maxBlocks; i++) {
|
||||
|
||||
sha1compression[i] = Sha1compression();
|
||||
sha1compression[i].dummy <== 0;
|
||||
|
||||
if (i==0) {
|
||||
for (k=0; k<32; k++) {
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../../sha2/sha256_temp/constants.circom";
|
||||
include "../../sha2/sha256_temp/sha256compression.circom";
|
||||
include "../../../bitify/comparators.circom";
|
||||
include "../../../bitify/bitify.circom";
|
||||
include "../../../utils/array.circom";
|
||||
|
||||
|
||||
/// @title Sha256Bytes
|
||||
/// @notice Computes the SHA256 hash of input bytes
|
||||
/// @input paddedIn Message to hash, padded as per the SHA256 specification; assumes to consist of bytes
|
||||
/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(8 * maxByteLength))` bits
|
||||
/// @output out The 256-bit hash of the input message
|
||||
template Sha256Bytes(maxByteLength) {
|
||||
signal input paddedIn[maxByteLength];
|
||||
signal input paddedInLength;
|
||||
signal output out[256];
|
||||
|
||||
var maxBits = maxByteLength * 8;
|
||||
component sha = Sha256General(maxBits);
|
||||
|
||||
component bytes[maxByteLength];
|
||||
for (var i = 0; i < maxByteLength; i++) {
|
||||
bytes[i] = Num2Bits(8);
|
||||
bytes[i].in <== paddedIn[i];
|
||||
for (var j = 0; j < 8; j++) {
|
||||
sha.paddedIn[i*8+j] <== bytes[i].out[7-j];
|
||||
}
|
||||
}
|
||||
sha.paddedInLength <== paddedInLength * 8;
|
||||
|
||||
for (var i = 0; i < 256; i++) {
|
||||
out[i] <== sha.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// @title Sha256General
|
||||
/// @notice A modified version of the SHA256 circuit that allows specified length messages up to a
|
||||
/// max to all work via array indexing on the SHA256 compression circuit.
|
||||
/// @input paddedIn Message to hash padded as per the SHA256 specification; assumes to consist of bits
|
||||
/// @input paddedInLength Length of the padded message; assumes to be in `ceil(log2(maxBitLength))` bits
|
||||
/// @output out The 256-bit hash of the input message
|
||||
template Sha256General(maxBitLength) {
|
||||
// maxBitLength must be a multiple of 512
|
||||
// the bit circuits in this file are limited to 15 so must be raised if the message is longer.
|
||||
assert(maxBitLength % 512 == 0);
|
||||
|
||||
var maxBitsPaddedBits = log2Ceil(maxBitLength);
|
||||
|
||||
// Note that maxBitLength = maxBits + 64
|
||||
signal input paddedIn[maxBitLength];
|
||||
signal input paddedInLength;
|
||||
|
||||
signal output out[256];
|
||||
|
||||
signal inBlockIndex;
|
||||
|
||||
var i;
|
||||
var k;
|
||||
var j;
|
||||
var maxBlocks;
|
||||
var bitsLastBlock;
|
||||
maxBlocks = (maxBitLength\512);
|
||||
|
||||
inBlockIndex <-- (paddedInLength >> 9);
|
||||
paddedInLength === inBlockIndex * 512;
|
||||
|
||||
// These verify the unconstrained floor calculation is the uniquely correct integer that represents the floor
|
||||
// component floorVerifierUnder = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits
|
||||
// floorVerifierUnder.in[0] <== (inBlockIndex)*512;
|
||||
// floorVerifierUnder.in[1] <== paddedInLength;
|
||||
// floorVerifierUnder.out === 1;
|
||||
|
||||
// component floorVerifierOver = GreaterThan(maxBitsPaddedBits);
|
||||
// floorVerifierOver.in[0] <== (inBlockIndex+1)*512;
|
||||
// floorVerifierOver.in[1] <== paddedInLength;
|
||||
// floorVerifierOver.out === 1;
|
||||
|
||||
// These verify we pass in a valid number of bits to the SHA256 compression circuit.
|
||||
component bitLengthVerifier = LessEqThan(maxBitsPaddedBits); // todo verify the length passed in is less than nbits. note that maxBitsPaddedBits can likely be lowered or made it a fn of maxbits
|
||||
bitLengthVerifier.in[0] <== paddedInLength;
|
||||
bitLengthVerifier.in[1] <== maxBitLength;
|
||||
bitLengthVerifier.out === 1;
|
||||
|
||||
// Note that we can no longer do padded verification efficiently inside the SHA because it requires non deterministic array indexing.
|
||||
// We can do it if we add a constraint, but since guessing a valid SHA2 preimage is hard anyways, we'll just do it outside the circuit.
|
||||
|
||||
// signal paddedIn[maxBlocks*512];
|
||||
// for (k=0; k<maxBits; k++) {
|
||||
// paddedIn[k] <== in[k];
|
||||
// }
|
||||
// paddedIn[maxBits] <== 1;
|
||||
// for (k=maxBits+1; k<maxBlocks*512-64; k++) {
|
||||
// paddedIn[k] <== 0;
|
||||
// }
|
||||
// for (k = 0; k< 64; k++) {
|
||||
// paddedIn[maxBlocks*512 - k -1] <== (maxBits >> k)&1;
|
||||
// }
|
||||
|
||||
component ha0 = H_sha256(0);
|
||||
component hb0 = H_sha256(1);
|
||||
component hc0 = H_sha256(2);
|
||||
component hd0 = H_sha256(3);
|
||||
component he0 = H_sha256(4);
|
||||
component hf0 = H_sha256(5);
|
||||
component hg0 = H_sha256(6);
|
||||
component hh0 = H_sha256(7);
|
||||
|
||||
component sha256compression[maxBlocks];
|
||||
|
||||
for (i=0; i<maxBlocks; i++) {
|
||||
sha256compression[i] = Sha256compression() ;
|
||||
|
||||
if (i==0) {
|
||||
for (k=0; k<32; k++ ) {
|
||||
sha256compression[i].hin[0*32+k] <== ha0.out[k];
|
||||
sha256compression[i].hin[1*32+k] <== hb0.out[k];
|
||||
sha256compression[i].hin[2*32+k] <== hc0.out[k];
|
||||
sha256compression[i].hin[3*32+k] <== hd0.out[k];
|
||||
sha256compression[i].hin[4*32+k] <== he0.out[k];
|
||||
sha256compression[i].hin[5*32+k] <== hf0.out[k];
|
||||
sha256compression[i].hin[6*32+k] <== hg0.out[k];
|
||||
sha256compression[i].hin[7*32+k] <== hh0.out[k];
|
||||
}
|
||||
} else {
|
||||
for (k=0; k<32; k++ ) {
|
||||
sha256compression[i].hin[32*0+k] <== sha256compression[i-1].out[32*0+31-k];
|
||||
sha256compression[i].hin[32*1+k] <== sha256compression[i-1].out[32*1+31-k];
|
||||
sha256compression[i].hin[32*2+k] <== sha256compression[i-1].out[32*2+31-k];
|
||||
sha256compression[i].hin[32*3+k] <== sha256compression[i-1].out[32*3+31-k];
|
||||
sha256compression[i].hin[32*4+k] <== sha256compression[i-1].out[32*4+31-k];
|
||||
sha256compression[i].hin[32*5+k] <== sha256compression[i-1].out[32*5+31-k];
|
||||
sha256compression[i].hin[32*6+k] <== sha256compression[i-1].out[32*6+31-k];
|
||||
sha256compression[i].hin[32*7+k] <== sha256compression[i-1].out[32*7+31-k];
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<512; k++) {
|
||||
sha256compression[i].inp[k] <== paddedIn[i*512+k];
|
||||
}
|
||||
}
|
||||
|
||||
// Select the correct compression output for the given length, instead of just the last one.
|
||||
component arraySelectors[256];
|
||||
for (k=0; k<256; k++) {
|
||||
arraySelectors[k] = ItemAtIndex(maxBlocks);
|
||||
for (j=0; j<maxBlocks; j++) {
|
||||
arraySelectors[k].in[j] <== sha256compression[j].out[k];
|
||||
}
|
||||
arraySelectors[k].index <== inBlockIndex - 1; // The index is 0 indexed and the block numbers are 1 indexed.
|
||||
out[k] <== arraySelectors[k].out;
|
||||
}
|
||||
|
||||
// for (k=0; k<256; k++) {
|
||||
// out[k] <== sha256compression[maxBlocks-1].out[k];
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../bitify/comparators.circom";
|
||||
include "../bitify/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// Some templates for num operations
|
||||
@@ -15,111 +15,6 @@ template Inverse(){
|
||||
out * in === 1;
|
||||
}
|
||||
|
||||
// THIS IS UNSECURE VERSION, NEVER (NEVER!!!!!!!!!!!!!) USE IT IN PRODUCTION!!!!
|
||||
// I hope secure version will appear later
|
||||
// use if u don`t know what is len of bit representation of in[0] is
|
||||
template DivisionStrict(){
|
||||
signal input in[2];
|
||||
|
||||
signal output mod;
|
||||
signal output div;
|
||||
|
||||
mod <-- in[0] % in[1];
|
||||
div <-- in[0] \ in[1];
|
||||
|
||||
div * in[1] + mod === in[0];
|
||||
component check1 = LessEqThan(252);
|
||||
component check2 = GreaterThan(252);
|
||||
|
||||
check1.in[0] <== div * in[1];
|
||||
check1.in[1] <== in[0];
|
||||
check1.out === 1;
|
||||
|
||||
check2.in[0] <== (div + 1) * in[1];
|
||||
check2.in[1] <== in[0];
|
||||
check2.out === 1;
|
||||
|
||||
}
|
||||
|
||||
// THIS IS UNSECURE VERSION, NEVER (NEVER!!!!!!!!!!!!!) USE IT IN PRODUCTION!!!!!
|
||||
// I hope secure version will appear later
|
||||
// use this if u know what len of bit representation of in[1] is
|
||||
template Division(LEN){
|
||||
|
||||
assert (LEN < 253);
|
||||
signal input in[2];
|
||||
|
||||
signal output div;
|
||||
signal output mod;
|
||||
|
||||
mod <-- in[0] % in[1];
|
||||
div <-- in[0] \ in[1];
|
||||
|
||||
div * in[1] + mod === in[0];
|
||||
component check1 = LessEqThan(LEN);
|
||||
component check2 = GreaterThan(LEN);
|
||||
|
||||
check1.in[0] <== div * in[1];
|
||||
check1.in[1] <== in[0];
|
||||
check1.out === 1;
|
||||
|
||||
check2.in[0] <== (div + 1) * in[1];
|
||||
check2.in[1] <== in[0];
|
||||
check2.out === 1;
|
||||
|
||||
}
|
||||
|
||||
// calculated log_2 rounded down (for example, 2.3 ===> 2)
|
||||
// also can be used as index of first 1 bit in number
|
||||
// don`t use it for 0!!!
|
||||
template Log2CeilStrict(){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal bits[252];
|
||||
component n2b = Num2Bits(252);
|
||||
n2b.in <== in - 1;
|
||||
n2b.out ==> bits;
|
||||
|
||||
signal counter[252];
|
||||
signal sum[252];
|
||||
|
||||
counter[0] <== bits[251];
|
||||
sum[0] <== counter[0];
|
||||
|
||||
for (var i = 1; i < 252; i++){
|
||||
counter[i] <== (1 - counter[i - 1]) * bits[251 - i] + counter[i - 1];
|
||||
sum[i] <== sum[i - 1] + counter[i];
|
||||
}
|
||||
|
||||
out <== sum[251];
|
||||
}
|
||||
|
||||
// to calculate log ceil, we should convert num to bits, and if we know it`s len, we already know the answer
|
||||
// but if u know estimed range of num, u can use this to reduce num of constraints (num < 2 ** RANGE)
|
||||
// (u don`t need to use convert num to 254 bits if u know that is always less that 1000, for example)
|
||||
template Log2Ceil(RANGE){
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal bits[RANGE];
|
||||
component n2b = Num2Bits(RANGE);
|
||||
n2b.in <== in - 1;
|
||||
n2b.out ==> bits;
|
||||
|
||||
signal counter[RANGE];
|
||||
signal sum[RANGE];
|
||||
|
||||
counter[0] <== bits[RANGE - 1];
|
||||
sum[0] <== counter[0];
|
||||
|
||||
for (var i = 1; i < RANGE; i++){
|
||||
counter[i] <== (1 - counter[i - 1]) * bits[RANGE - 1 - i] + counter[i - 1];
|
||||
sum[i] <== sum[i - 1] + counter[i];
|
||||
}
|
||||
|
||||
out <== sum[RANGE - 1];
|
||||
}
|
||||
|
||||
// computes last bit of num with any bit len for 2 constraints
|
||||
// returns bit (0 or 1) and div = num \ 2
|
||||
@@ -161,14 +56,10 @@ template GetLastNBits(N){
|
||||
|
||||
// Get sum of N elements with 1 constraint.
|
||||
// Use this instead of a + b + ... + c;
|
||||
// Circom will drop linear constaraint because of optimisation
|
||||
// This one adds dummy * dummy (0) to make it quadratic
|
||||
template GetSumOfNElements(N){
|
||||
assert (N >= 2);
|
||||
|
||||
signal input in[N];
|
||||
signal input dummy;
|
||||
dummy * dummy === 0;
|
||||
signal output out;
|
||||
|
||||
signal sum[N - 1];
|
||||
@@ -180,5 +71,5 @@ template GetSumOfNElements(N){
|
||||
sum[i] <== sum[i - 1] + in[i + 1];
|
||||
}
|
||||
}
|
||||
out <== sum[N - 2] + dummy * dummy;
|
||||
out <== sum[N - 2];
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.6;
|
||||
|
||||
include "../../circomlib/hasher/hash.circom";
|
||||
include "../../circomlib/bitify/comparators.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "../../circomlib/mux/mux1.circom";
|
||||
|
||||
// This circuit is designed to calculate the root of a binary Merkle
|
||||
@@ -36,7 +36,7 @@ template BinaryMerkleRoot(MAX_DEPTH) {
|
||||
var c[2][2] = [ [nodes[i], siblings[i]], [siblings[i], nodes[i]] ];
|
||||
var childNodes[2] = MultiMux1(2)(c, indices[i]);
|
||||
|
||||
nodes[i + 1] <== PoseidonHash(2)(childNodes, 0);
|
||||
nodes[i + 1] <== PoseidonHash(2)(childNodes);
|
||||
}
|
||||
|
||||
var isDepth = IsEqual()([depth, MAX_DEPTH]);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../bitify/comparators.circom";
|
||||
include "../bitify/bitify.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
// Computes the first n common bits of the hashes
|
||||
template CommonBitsLengthFromEnd() {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "../hasher/hash.circom";
|
||||
include "../bitify/comparators.circom";
|
||||
include "../bitify/bitify.circom";
|
||||
include "../utils/array.circom";
|
||||
include "circomlib/circuits/comparators.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
include "@zk-email/circuits/utils/array.circom";
|
||||
include "binary-merkle-root.circom";
|
||||
include "getCommonLength.circom";
|
||||
|
||||
@@ -31,7 +31,7 @@ template SMTVerify(nLength) {
|
||||
path <== ct1.out;
|
||||
|
||||
// Closest_key to leaf
|
||||
signal leaf <== PoseidonHash(3)([value, 1, 1], 0); // compute the leaf from the value
|
||||
signal leaf <== PoseidonHash(3)([value, 1, 1]); // compute the leaf from the value
|
||||
signal isClosestZero <== IsEqual()([value,0]); // check if the inital value is 0, in that case the leaf will be 0 too, not Hash(0,1,1);
|
||||
signal leafOrZero <== leaf * (1 - isClosestZero);
|
||||
|
||||
@@ -40,7 +40,7 @@ template SMTVerify(nLength) {
|
||||
signal computedRootIsValid <== IsEqual()([computedRoot,root]);
|
||||
|
||||
// check is leaf equals virtual leaf
|
||||
signal virtualLeaf <== PoseidonHash(3)([virtualValue, 1,1], 0);
|
||||
signal virtualLeaf <== PoseidonHash(3)([virtualValue, 1,1]);
|
||||
signal areLeafAndVirtualLeafEquals <== IsEqual()([virtualLeaf, leaf]);
|
||||
|
||||
signal isInclusionOrNonInclusionValid <== IsEqual()([mode,areLeafAndVirtualLeafEquals]);
|
||||
|
||||
@@ -19,7 +19,6 @@ template verifyECDSABits(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, ALGO){
|
||||
signal input pubkey[2][CHUNK_NUMBER];
|
||||
signal input signature[2][CHUNK_NUMBER];
|
||||
signal input hashed[ALGO];
|
||||
signal input dummy;
|
||||
|
||||
signal hashedChunked[CHUNK_NUMBER];
|
||||
|
||||
@@ -43,7 +42,6 @@ template verifyECDSABits(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, ALGO){
|
||||
|
||||
modInv.in <== signature[1];
|
||||
modInv.modulus <== order;
|
||||
modInv.dummy <== dummy;
|
||||
modInv.out ==> sinv;
|
||||
|
||||
// (s ^ -1 mod n) * h mod n
|
||||
@@ -51,31 +49,26 @@ template verifyECDSABits(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, ALGO){
|
||||
mult.in[0] <== sinv;
|
||||
mult.in[1] <== hashedChunked;
|
||||
mult.in[2] <== order;
|
||||
mult.dummy <== dummy;
|
||||
|
||||
// (s ^ -1 mod n) * r mod n
|
||||
component mult2 = BigMultModPNonOptimised(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
mult2.in[0] <== sinv;
|
||||
mult2.in[1] <== signature[0];
|
||||
mult2.in[2] <== order;
|
||||
mult2.dummy <== dummy;
|
||||
|
||||
// h * s_inv * G
|
||||
component scalarMult1 = EllipicCurveScalarGeneratorMultiplication(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
scalarMult1.scalar <== mult.out;
|
||||
scalarMult1.dummy <== dummy;
|
||||
|
||||
// r * s_inv * (x, y)
|
||||
component scalarMult2 = EllipticCurvePipingerMult(CHUNK_SIZE, CHUNK_NUMBER, A, B, P, 4);
|
||||
scalarMult2.scalar <== mult2.out;
|
||||
scalarMult2.in <== pubkey;
|
||||
scalarMult2.dummy <== dummy;
|
||||
|
||||
// (x1, y1) = h * s_inv * G + r * s_inv * (x, y)
|
||||
component add = EllipticCurveAdd(CHUNK_SIZE, CHUNK_NUMBER, A, B, P);
|
||||
add.in1 <== scalarMult1.out;
|
||||
add.in2 <== scalarMult2.out;
|
||||
add.dummy <== dummy;
|
||||
|
||||
// x1 === r
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++){
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
// PKCS1v1.5 Padding Scheme
|
||||
// 0x00 || 0x01 || PS || 0x00 || OID || Hash
|
||||
// PS is a sequence of 0xFF bytes that is padded so that the data to be signed matches the length of the key.
|
||||
// OID is the object identifier for the hash function used.
|
||||
// For SHA1, the OID is 0x3021300906052b0e03021a05000414
|
||||
// For SHA256, the OID is 0x3031300d060960864801650304020105000420
|
||||
// For SHA384, the OID is 0x3041300d060960864801650304020205000430
|
||||
// For SHA512, the OID is 0x3051300d060960864801650304020305000440
|
||||
|
||||
template Pkcs1v1_5Padding(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) {
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
signal input message[CHUNK_NUMBER];
|
||||
|
||||
signal output out[CHUNK_NUMBER];
|
||||
|
||||
var OID_SIZE = getOIDSize(HASH_SIZE);
|
||||
|
||||
signal paddedMessageBits[CHUNK_SIZE * CHUNK_NUMBER];
|
||||
|
||||
component modulusN2B[CHUNK_NUMBER];
|
||||
component messageN2B[CHUNK_NUMBER];
|
||||
signal modulusBits[CHUNK_SIZE * CHUNK_NUMBER];
|
||||
signal messageBits[CHUNK_SIZE * CHUNK_NUMBER];
|
||||
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
messageN2B[i] = Num2Bits(CHUNK_SIZE);
|
||||
messageN2B[i].in <== message[i];
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
messageBits[i*CHUNK_SIZE+j] <== messageN2B[i].out[j];
|
||||
}
|
||||
modulusN2B[i] = Num2Bits(CHUNK_SIZE);
|
||||
modulusN2B[i].in <== modulus[i];
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
modulusBits[i*CHUNK_SIZE+j] <== modulusN2B[i].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < HASH_SIZE; i++) {
|
||||
paddedMessageBits[i] <== messageBits[i];
|
||||
}
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
paddedMessageBits[HASH_SIZE + OID_SIZE + i] <== 0;
|
||||
}
|
||||
|
||||
var OID = getOID(HASH_SIZE);
|
||||
for (var i = HASH_SIZE; i < HASH_SIZE + OID_SIZE; i++) {
|
||||
paddedMessageBits[i] <== (OID >> (i - HASH_SIZE)) & 1;
|
||||
}
|
||||
|
||||
component modulusZero[(CHUNK_SIZE * CHUNK_NUMBER + 7 - (HASH_SIZE + OID_SIZE)) \ 8];
|
||||
{
|
||||
var modulusPrefix = 0;
|
||||
for (var i = CHUNK_SIZE * CHUNK_NUMBER - 1; i >= (HASH_SIZE + OID_SIZE) + 8; i--) {
|
||||
if (i + 8 < CHUNK_SIZE * CHUNK_NUMBER) {
|
||||
modulusPrefix += modulusBits[i+8];
|
||||
if (i % 8 == 0) {
|
||||
var idx = (i - (HASH_SIZE + OID_SIZE)) \ 8;
|
||||
modulusZero[idx] = IsZero();
|
||||
modulusZero[idx].in <== modulusPrefix;
|
||||
paddedMessageBits[i] <== 1-modulusZero[idx].out;
|
||||
} else {
|
||||
paddedMessageBits[i] <== paddedMessageBits[i+1];
|
||||
}
|
||||
} else {
|
||||
paddedMessageBits[i] <== 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(HASH_SIZE + OID_SIZE + 8 + 65 < CHUNK_SIZE * CHUNK_NUMBER);
|
||||
|
||||
for (var i = HASH_SIZE + OID_SIZE + 8; i < HASH_SIZE + OID_SIZE + 8 + 65; i++) {
|
||||
paddedMessageBits[i] === 1;
|
||||
}
|
||||
|
||||
component passedMessageB2N[CHUNK_NUMBER];
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
passedMessageB2N[i] = Bits2Num(CHUNK_SIZE);
|
||||
for (var j = 0; j < CHUNK_SIZE; j++) {
|
||||
passedMessageB2N[i].in[j] <== paddedMessageBits[i*CHUNK_SIZE+j];
|
||||
}
|
||||
out[i] <== passedMessageB2N[i].out;
|
||||
}
|
||||
}
|
||||
|
||||
function getOID(HASH_SIZE) {
|
||||
if (HASH_SIZE == 160) {
|
||||
return 0x3021300906052b0e03021a05000414;
|
||||
}
|
||||
if (HASH_SIZE == 256) {
|
||||
return 0x3031300d060960864801650304020105000420;
|
||||
}
|
||||
if (HASH_SIZE == 384) {
|
||||
return 0x3041300d060960864801650304020205000430;
|
||||
}
|
||||
if (HASH_SIZE == 512) {
|
||||
return 0x3051300d060960864801650304020305000440;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getOIDSize(HASH_SIZE) {
|
||||
if (HASH_SIZE == 160) {
|
||||
return 120;
|
||||
}
|
||||
if (HASH_SIZE == 256) {
|
||||
return 152;
|
||||
}
|
||||
if (HASH_SIZE == 384) {
|
||||
return 152;
|
||||
}
|
||||
if (HASH_SIZE == 512) {
|
||||
return 152;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
pragma circom 2.1.9;
|
||||
|
||||
include "@zk-email/circuits/lib/fp.circom";
|
||||
include "./pkcs1v1_5Padding.circom";
|
||||
include "circomlib/circuits/bitify.circom";
|
||||
|
||||
// For 2048bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 32
|
||||
// For 3072bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 48
|
||||
// For 4096bits RSA, CHUNK_SIZE = 64, CHUNK_NUMBER = 64
|
||||
|
||||
// HASH_SIZE is the size of the hash in bits
|
||||
|
||||
template VerifyRsa3Pkcs1v1_5(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE) {
|
||||
signal input signature[CHUNK_NUMBER];
|
||||
signal input modulus[CHUNK_NUMBER];
|
||||
|
||||
signal input message[CHUNK_NUMBER];
|
||||
|
||||
// 1. Add padding to the hashed message
|
||||
component padder = Pkcs1v1_5Padding(CHUNK_SIZE, CHUNK_NUMBER, HASH_SIZE);
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
padder.modulus[i] <== modulus[i];
|
||||
padder.message[i] <== message[i];
|
||||
}
|
||||
|
||||
// 2. Check that the signature is in proper form and reduced mod modulus.
|
||||
component signatureRangeCheck[CHUNK_NUMBER];
|
||||
component bigLessThan = BigLessThan(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
signatureRangeCheck[i] = Num2Bits(CHUNK_SIZE);
|
||||
signatureRangeCheck[i].in <== signature[i];
|
||||
bigLessThan.a[i] <== signature[i];
|
||||
bigLessThan.b[i] <== modulus[i];
|
||||
}
|
||||
bigLessThan.out === 1;
|
||||
|
||||
// 3. Compute the signature^exponent mod modulus
|
||||
component bigPow = FpPow3Mod(CHUNK_SIZE, CHUNK_NUMBER);
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
bigPow.base[i] <== signature[i];
|
||||
bigPow.modulus[i] <== modulus[i];
|
||||
}
|
||||
|
||||
// 4. Check that the computed value is equal to the padded message
|
||||
for (var i = 0; i < CHUNK_NUMBER; i++) {
|
||||
bigPow.out[i] === padder.out[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// @title FpPow3Mod
|
||||
/// @notice Computes base^3 mod modulus
|
||||
/// @dev Does not necessarily reduce fully mod modulus (the answer could be too big by a multiple of modulus)
|
||||
/// @param n Number of bits per chunk the modulus is split into.
|
||||
/// @param k Number of chunks the modulus is split into.
|
||||
/// @input base The base to exponentiate; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @input modulus The modulus; assumes to consist of `k` chunks, each of which must fit in `n` bits
|
||||
/// @output out The result of the exponentiation.
|
||||
template FpPow3Mod(n, k) {
|
||||
signal input base[k];
|
||||
signal input modulus[k];
|
||||
|
||||
signal output out[k];
|
||||
|
||||
component doublers = FpMul(n, k);
|
||||
component adder = FpMul(n, k);
|
||||
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.p[j] <== modulus[j];
|
||||
doublers.p[j] <== modulus[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
doublers.a[j] <== base[j];
|
||||
doublers.b[j] <== base[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
adder.a[j] <== base[j];
|
||||
adder.b[j] <== doublers.out[j];
|
||||
}
|
||||
for (var j = 0; j < k; j++) {
|
||||
out[j] <== adder.out[j];
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user