├── LICENSE
├── README.md
├── android
├── .gitignore
├── .idea
│ ├── .name
│ ├── codeStyles
│ │ └── Project.xml
│ ├── gradle.xml
│ ├── misc.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── punchcard
│ │ │ └── ExampleInstrumentedTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── punchcard
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── RustPunchCard.java
│ │ ├── jniLibs
│ │ │ ├── arm64
│ │ │ │ └── libcargo.so
│ │ │ ├── armeabi
│ │ │ │ └── libcargo.so
│ │ │ └── x86
│ │ │ │ └── libcargo.so
│ │ └── res
│ │ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── drawable
│ │ │ └── ic_launcher_background.xml
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── punchcard
│ │ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── build.sh
├── cargo-config.toml
├── cargo
├── .gitignore
├── Cargo.lock
├── Cargo.toml
└── src
│ ├── bin.rs
│ ├── crypto.rs
│ ├── crypto_pairing.rs
│ ├── lib.rs
│ └── lib
│ ├── crypto.rs
│ └── crypto_pairing.rs
└── data.txt
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2021, Saba Eskandarian
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This code accompanies the paper "Fast Privacy-Preserving Punch Cards" (https://eprint.iacr.org/2020/741.pdf)
2 |
3 | `data.txt` contains the evaluation results that appear in the paper. The performance numbers labeled "computer" were taken on a laptop with an intel i5-8265U processer @ 1.60 GHz running Ubuntu Linux. The "Google Pixel" numbers were measured on the Google Pixel (first generation) phone. Measurements were taken in spring 2020 with both devices running up to date versions of their respective operating systems.
4 |
5 | If you want to run the code on Android, add NDK according to directions at https://mozilla.github.io/firefox-browser-architecture/experiments/2017-09-21-rust-on-android.html. Then uncomment the commented lines in `build.sh`
6 |
7 | To test the code locally, simply run `./build.sh` and then `./cargo/target/release/mybin`. You will need Rust installed.
8 |
9 | The source code is set to run the standard version of our scheme that uses curve25519. To run the mergeable scheme that uses pairings, you will need to change line 45 of `/cargo/src/lib.rs` from `test_type: Tests::Group,` to `test_type: Tests::Pairing,`.
10 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/android/.idea/.name:
--------------------------------------------------------------------------------
1 | Punch Card
--------------------------------------------------------------------------------
/android/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/android/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/android/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 29
5 | buildToolsVersion "29.0.3"
6 | ndkVersion "21.0.6113669"
7 |
8 | defaultConfig {
9 | applicationId "com.example.punchcard"
10 | minSdkVersion 26
11 | targetSdkVersion 29
12 | versionCode 1
13 | versionName "1.0"
14 |
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 |
17 | ndk {
18 | abiFilters "arm64", "armeabi", "x86"
19 | }
20 | }
21 |
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 |
29 | }
30 |
31 | dependencies {
32 | implementation fileTree(dir: 'libs', include: ['*.jar'])
33 |
34 | implementation 'androidx.appcompat:appcompat:1.0.2'
35 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
36 | testImplementation 'junit:junit:4.12'
37 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
38 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
39 | }
40 |
--------------------------------------------------------------------------------
/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/android/app/src/androidTest/java/com/example/punchcard/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.punchcard;
2 |
3 | import android.content.Context;
4 |
5 | import androidx.test.platform.app.InstrumentationRegistry;
6 | import androidx.test.ext.junit.runners.AndroidJUnit4;
7 |
8 | import org.junit.Test;
9 | import org.junit.runner.RunWith;
10 |
11 | import static org.junit.Assert.*;
12 |
13 | /**
14 | * Instrumented test, which will execute on an Android device.
15 | *
16 | * @see Testing documentation
17 | */
18 | @RunWith(AndroidJUnit4.class)
19 | public class ExampleInstrumentedTest {
20 | @Test
21 | public void useAppContext() {
22 | // Context of the app under test.
23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
24 |
25 | assertEquals("com.example.punchcard", appContext.getPackageName());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/punchcard/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.punchcard;
2 |
3 | import androidx.appcompat.app.AppCompatActivity;
4 |
5 | import android.os.Bundle;
6 | import android.widget.TextView;
7 |
8 | public class MainActivity extends AppCompatActivity {
9 |
10 | static {
11 | System.loadLibrary("cargo");
12 | }
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_main);
18 |
19 | RustPunchCard g = new RustPunchCard();
20 | String r = g.runRustCode();
21 | ((TextView)findViewById(R.id.outputField)).setText(r);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/punchcard/RustPunchCard.java:
--------------------------------------------------------------------------------
1 | package com.example.punchcard;
2 |
3 | public class RustPunchCard {
4 | private static native String benchmarkCode();
5 |
6 | public String runRustCode() {
7 | return benchmarkCode();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/android/app/src/main/jniLibs/arm64/libcargo.so:
--------------------------------------------------------------------------------
1 | /home/saba/Code/PunchCard/cargo/target/aarch64-linux-android/release/libcargo.so
--------------------------------------------------------------------------------
/android/app/src/main/jniLibs/armeabi/libcargo.so:
--------------------------------------------------------------------------------
1 | /home/saba/Code/PunchCard/cargo/target/armv7-linux-androideabi/release/libcargo.so
--------------------------------------------------------------------------------
/android/app/src/main/jniLibs/x86/libcargo.so:
--------------------------------------------------------------------------------
1 | /home/saba/Code/PunchCard/cargo/target/i686-linux-android/release/libcargo.so
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/android/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Punch Card
3 |
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/android/app/src/test/java/com/example/punchcard/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.punchcard;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 |
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.6.1'
12 |
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 |
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 |
21 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SabaEskandarian/PunchCard/0dbad68cb66c6ec3f2b14930c51e98f4b957084b/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Mar 18 11:44:12 PDT 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name='Punch Card'
2 | include ':app'
3 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | cd cargo
2 | cargo build --release
3 | #cargo build --target aarch64-linux-android --release
4 | #cargo build --target armv7-linux-androideabi --release
5 | #cargo build --target i686-linux-android --release
6 |
--------------------------------------------------------------------------------
/cargo-config.toml:
--------------------------------------------------------------------------------
1 | [target.aarch64-linux-android]
2 | ar = "/home/saba/Code/PunchCard/NDK/arm64/bin/aarch64-linux-android-ar"
3 | linker = "/home/saba/Code/PunchCard/NDK/arm64/bin/aarch64-linux-android-clang"
4 |
5 | [target.armv7-linux-androideabi]
6 | ar = "/home/saba/Code/PunchCard/NDK/arm/bin/arm-linux-androideabi-ar"
7 | linker = "/home/saba/Code/PunchCard/NDK/arm/bin/arm-linux-androideabi-clang"
8 |
9 | [target.i686-linux-android]
10 | ar = "/home/saba/Code/PunchCard/NDK/x86/bin/i686-linux-android-ar"
11 | linker = "/home/saba/Code/PunchCard/NDK/x86/bin/i686-linux-android-clang"
12 |
13 |
--------------------------------------------------------------------------------
/cargo/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/cargo/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "ascii"
5 | version = "0.7.1"
6 | source = "registry+https://github.com/rust-lang/crates.io-index"
7 | checksum = "3ae7d751998c189c1d4468cf0a39bb2eae052a9c58d50ebb3b9591ee3813ad50"
8 |
9 | [[package]]
10 | name = "autocfg"
11 | version = "1.0.0"
12 | source = "registry+https://github.com/rust-lang/crates.io-index"
13 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
14 |
15 | [[package]]
16 | name = "block-buffer"
17 | version = "0.7.3"
18 | source = "registry+https://github.com/rust-lang/crates.io-index"
19 | checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
20 | dependencies = [
21 | "block-padding",
22 | "byte-tools",
23 | "byteorder",
24 | "generic-array",
25 | ]
26 |
27 | [[package]]
28 | name = "block-padding"
29 | version = "0.1.5"
30 | source = "registry+https://github.com/rust-lang/crates.io-index"
31 | checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
32 | dependencies = [
33 | "byte-tools",
34 | ]
35 |
36 | [[package]]
37 | name = "byte-tools"
38 | version = "0.3.1"
39 | source = "registry+https://github.com/rust-lang/crates.io-index"
40 | checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
41 |
42 | [[package]]
43 | name = "byteorder"
44 | version = "1.3.4"
45 | source = "registry+https://github.com/rust-lang/crates.io-index"
46 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
47 |
48 | [[package]]
49 | name = "cargo"
50 | version = "0.1.0"
51 | dependencies = [
52 | "curve25519-dalek",
53 | "ff-zeroize",
54 | "jni",
55 | "pairing-plus",
56 | "rand 0.7.3",
57 | "rand_core 0.5.1",
58 | "sha2",
59 | ]
60 |
61 | [[package]]
62 | name = "cesu8"
63 | version = "1.1.0"
64 | source = "registry+https://github.com/rust-lang/crates.io-index"
65 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
66 |
67 | [[package]]
68 | name = "cfg-if"
69 | version = "0.1.10"
70 | source = "registry+https://github.com/rust-lang/crates.io-index"
71 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
72 |
73 | [[package]]
74 | name = "combine"
75 | version = "2.5.2"
76 | source = "registry+https://github.com/rust-lang/crates.io-index"
77 | checksum = "1645a65a99c7c8d345761f4b75a6ffe5be3b3b27a93ee731fccc5050ba6be97c"
78 | dependencies = [
79 | "ascii",
80 | "byteorder",
81 | ]
82 |
83 | [[package]]
84 | name = "curve25519-dalek"
85 | version = "2.0.0"
86 | source = "registry+https://github.com/rust-lang/crates.io-index"
87 | checksum = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839"
88 | dependencies = [
89 | "byteorder",
90 | "digest",
91 | "rand_core 0.5.1",
92 | "subtle",
93 | "zeroize",
94 | ]
95 |
96 | [[package]]
97 | name = "digest"
98 | version = "0.8.1"
99 | source = "registry+https://github.com/rust-lang/crates.io-index"
100 | checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
101 | dependencies = [
102 | "generic-array",
103 | ]
104 |
105 | [[package]]
106 | name = "error-chain"
107 | version = "0.10.0"
108 | source = "registry+https://github.com/rust-lang/crates.io-index"
109 | checksum = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
110 |
111 | [[package]]
112 | name = "fake-simd"
113 | version = "0.1.2"
114 | source = "registry+https://github.com/rust-lang/crates.io-index"
115 | checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
116 |
117 | [[package]]
118 | name = "ff-zeroize"
119 | version = "0.6.3"
120 | source = "registry+https://github.com/rust-lang/crates.io-index"
121 | checksum = "c02169a2e8515aa316ce516eaaf6318a76617839fbf904073284bc2576b029ee"
122 | dependencies = [
123 | "byteorder",
124 | "ff_derive-zeroize",
125 | "rand_core 0.5.1",
126 | "zeroize",
127 | ]
128 |
129 | [[package]]
130 | name = "ff_derive-zeroize"
131 | version = "0.6.2"
132 | source = "registry+https://github.com/rust-lang/crates.io-index"
133 | checksum = "b24d4059bc0d0a0bf26b740aa21af1f96a984f0ab7a21356d00b32475388b53a"
134 | dependencies = [
135 | "num-bigint",
136 | "num-integer",
137 | "num-traits",
138 | "proc-macro2",
139 | "quote",
140 | "syn",
141 | ]
142 |
143 | [[package]]
144 | name = "fuchsia-cprng"
145 | version = "0.1.1"
146 | source = "registry+https://github.com/rust-lang/crates.io-index"
147 | checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
148 |
149 | [[package]]
150 | name = "generic-array"
151 | version = "0.12.3"
152 | source = "registry+https://github.com/rust-lang/crates.io-index"
153 | checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
154 | dependencies = [
155 | "typenum",
156 | ]
157 |
158 | [[package]]
159 | name = "getrandom"
160 | version = "0.1.14"
161 | source = "registry+https://github.com/rust-lang/crates.io-index"
162 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
163 | dependencies = [
164 | "cfg-if",
165 | "libc",
166 | "wasi",
167 | ]
168 |
169 | [[package]]
170 | name = "jni"
171 | version = "0.5.3"
172 | source = "registry+https://github.com/rust-lang/crates.io-index"
173 | checksum = "cffc930ce6a38a4013e30567b559bdc79f601013ba4a81e65dbda9207263efd4"
174 | dependencies = [
175 | "cesu8",
176 | "combine",
177 | "error-chain",
178 | "jni-sys",
179 | "log 0.3.9",
180 | ]
181 |
182 | [[package]]
183 | name = "jni-sys"
184 | version = "0.2.5"
185 | source = "registry+https://github.com/rust-lang/crates.io-index"
186 | checksum = "de0aaaba8809ab8d83a53fe2b313b996b79e8632b855eae9f70ad4323dca91b8"
187 |
188 | [[package]]
189 | name = "libc"
190 | version = "0.2.68"
191 | source = "registry+https://github.com/rust-lang/crates.io-index"
192 | checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
193 |
194 | [[package]]
195 | name = "log"
196 | version = "0.3.9"
197 | source = "registry+https://github.com/rust-lang/crates.io-index"
198 | checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
199 | dependencies = [
200 | "log 0.4.8",
201 | ]
202 |
203 | [[package]]
204 | name = "log"
205 | version = "0.4.8"
206 | source = "registry+https://github.com/rust-lang/crates.io-index"
207 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
208 | dependencies = [
209 | "cfg-if",
210 | ]
211 |
212 | [[package]]
213 | name = "num-bigint"
214 | version = "0.2.6"
215 | source = "registry+https://github.com/rust-lang/crates.io-index"
216 | checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
217 | dependencies = [
218 | "autocfg",
219 | "num-integer",
220 | "num-traits",
221 | ]
222 |
223 | [[package]]
224 | name = "num-integer"
225 | version = "0.1.42"
226 | source = "registry+https://github.com/rust-lang/crates.io-index"
227 | checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
228 | dependencies = [
229 | "autocfg",
230 | "num-traits",
231 | ]
232 |
233 | [[package]]
234 | name = "num-traits"
235 | version = "0.2.11"
236 | source = "registry+https://github.com/rust-lang/crates.io-index"
237 | checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
238 | dependencies = [
239 | "autocfg",
240 | ]
241 |
242 | [[package]]
243 | name = "opaque-debug"
244 | version = "0.2.3"
245 | source = "registry+https://github.com/rust-lang/crates.io-index"
246 | checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
247 |
248 | [[package]]
249 | name = "pairing-plus"
250 | version = "0.18.0"
251 | source = "registry+https://github.com/rust-lang/crates.io-index"
252 | checksum = "e819a65319e20573a060d027524e937f6b9c318b33215a6f0aa77726813e35c1"
253 | dependencies = [
254 | "byteorder",
255 | "digest",
256 | "ff-zeroize",
257 | "rand 0.4.6",
258 | "rand_core 0.5.1",
259 | "rand_xorshift",
260 | "zeroize",
261 | ]
262 |
263 | [[package]]
264 | name = "ppv-lite86"
265 | version = "0.2.6"
266 | source = "registry+https://github.com/rust-lang/crates.io-index"
267 | checksum = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
268 |
269 | [[package]]
270 | name = "proc-macro2"
271 | version = "1.0.9"
272 | source = "registry+https://github.com/rust-lang/crates.io-index"
273 | checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
274 | dependencies = [
275 | "unicode-xid",
276 | ]
277 |
278 | [[package]]
279 | name = "quote"
280 | version = "1.0.3"
281 | source = "registry+https://github.com/rust-lang/crates.io-index"
282 | checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
283 | dependencies = [
284 | "proc-macro2",
285 | ]
286 |
287 | [[package]]
288 | name = "rand"
289 | version = "0.4.6"
290 | source = "registry+https://github.com/rust-lang/crates.io-index"
291 | checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
292 | dependencies = [
293 | "fuchsia-cprng",
294 | "libc",
295 | "rand_core 0.3.1",
296 | "rdrand",
297 | "winapi",
298 | ]
299 |
300 | [[package]]
301 | name = "rand"
302 | version = "0.7.3"
303 | source = "registry+https://github.com/rust-lang/crates.io-index"
304 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
305 | dependencies = [
306 | "getrandom",
307 | "libc",
308 | "rand_chacha",
309 | "rand_core 0.5.1",
310 | "rand_hc",
311 | ]
312 |
313 | [[package]]
314 | name = "rand_chacha"
315 | version = "0.2.2"
316 | source = "registry+https://github.com/rust-lang/crates.io-index"
317 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
318 | dependencies = [
319 | "ppv-lite86",
320 | "rand_core 0.5.1",
321 | ]
322 |
323 | [[package]]
324 | name = "rand_core"
325 | version = "0.3.1"
326 | source = "registry+https://github.com/rust-lang/crates.io-index"
327 | checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
328 | dependencies = [
329 | "rand_core 0.4.2",
330 | ]
331 |
332 | [[package]]
333 | name = "rand_core"
334 | version = "0.4.2"
335 | source = "registry+https://github.com/rust-lang/crates.io-index"
336 | checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
337 |
338 | [[package]]
339 | name = "rand_core"
340 | version = "0.5.1"
341 | source = "registry+https://github.com/rust-lang/crates.io-index"
342 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
343 | dependencies = [
344 | "getrandom",
345 | ]
346 |
347 | [[package]]
348 | name = "rand_hc"
349 | version = "0.2.0"
350 | source = "registry+https://github.com/rust-lang/crates.io-index"
351 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
352 | dependencies = [
353 | "rand_core 0.5.1",
354 | ]
355 |
356 | [[package]]
357 | name = "rand_xorshift"
358 | version = "0.2.0"
359 | source = "registry+https://github.com/rust-lang/crates.io-index"
360 | checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
361 | dependencies = [
362 | "rand_core 0.5.1",
363 | ]
364 |
365 | [[package]]
366 | name = "rdrand"
367 | version = "0.4.0"
368 | source = "registry+https://github.com/rust-lang/crates.io-index"
369 | checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
370 | dependencies = [
371 | "rand_core 0.3.1",
372 | ]
373 |
374 | [[package]]
375 | name = "sha2"
376 | version = "0.8.1"
377 | source = "registry+https://github.com/rust-lang/crates.io-index"
378 | checksum = "27044adfd2e1f077f649f59deb9490d3941d674002f7d062870a60ebe9bd47a0"
379 | dependencies = [
380 | "block-buffer",
381 | "digest",
382 | "fake-simd",
383 | "opaque-debug",
384 | ]
385 |
386 | [[package]]
387 | name = "subtle"
388 | version = "2.2.2"
389 | source = "registry+https://github.com/rust-lang/crates.io-index"
390 | checksum = "7c65d530b10ccaeac294f349038a597e435b18fb456aadd0840a623f83b9e941"
391 |
392 | [[package]]
393 | name = "syn"
394 | version = "1.0.17"
395 | source = "registry+https://github.com/rust-lang/crates.io-index"
396 | checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
397 | dependencies = [
398 | "proc-macro2",
399 | "quote",
400 | "unicode-xid",
401 | ]
402 |
403 | [[package]]
404 | name = "synstructure"
405 | version = "0.12.3"
406 | source = "registry+https://github.com/rust-lang/crates.io-index"
407 | checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
408 | dependencies = [
409 | "proc-macro2",
410 | "quote",
411 | "syn",
412 | "unicode-xid",
413 | ]
414 |
415 | [[package]]
416 | name = "typenum"
417 | version = "1.11.2"
418 | source = "registry+https://github.com/rust-lang/crates.io-index"
419 | checksum = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
420 |
421 | [[package]]
422 | name = "unicode-xid"
423 | version = "0.2.0"
424 | source = "registry+https://github.com/rust-lang/crates.io-index"
425 | checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
426 |
427 | [[package]]
428 | name = "wasi"
429 | version = "0.9.0+wasi-snapshot-preview1"
430 | source = "registry+https://github.com/rust-lang/crates.io-index"
431 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
432 |
433 | [[package]]
434 | name = "winapi"
435 | version = "0.3.8"
436 | source = "registry+https://github.com/rust-lang/crates.io-index"
437 | checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
438 | dependencies = [
439 | "winapi-i686-pc-windows-gnu",
440 | "winapi-x86_64-pc-windows-gnu",
441 | ]
442 |
443 | [[package]]
444 | name = "winapi-i686-pc-windows-gnu"
445 | version = "0.4.0"
446 | source = "registry+https://github.com/rust-lang/crates.io-index"
447 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
448 |
449 | [[package]]
450 | name = "winapi-x86_64-pc-windows-gnu"
451 | version = "0.4.0"
452 | source = "registry+https://github.com/rust-lang/crates.io-index"
453 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
454 |
455 | [[package]]
456 | name = "zeroize"
457 | version = "1.1.0"
458 | source = "registry+https://github.com/rust-lang/crates.io-index"
459 | checksum = "3cbac2ed2ba24cc90f5e06485ac8c7c1e5449fe8911aef4d8877218af021a5b8"
460 | dependencies = [
461 | "zeroize_derive",
462 | ]
463 |
464 | [[package]]
465 | name = "zeroize_derive"
466 | version = "1.0.0"
467 | source = "registry+https://github.com/rust-lang/crates.io-index"
468 | checksum = "de251eec69fc7c1bc3923403d18ececb929380e016afe103da75f396704f8ca2"
469 | dependencies = [
470 | "proc-macro2",
471 | "quote",
472 | "syn",
473 | "synstructure",
474 | ]
475 |
--------------------------------------------------------------------------------
/cargo/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cargo"
3 | version = "0.1.0"
4 | authors = ["SabaEskandarian "]
5 | edition = "2018"
6 |
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8 |
9 |
10 | [target.'cfg(target_os="android")'.dependencies]
11 | jni = { version = "0.5", default-features = false }
12 |
13 | [lib]
14 | crate-type = ["dylib"]
15 | path = "src/lib.rs"
16 |
17 | [[bin]]
18 | name = "mybin"
19 | path = "src/bin.rs"
20 |
21 | [dependencies]
22 | curve25519-dalek = "2"
23 | sha2 = "0.8"
24 | rand_core = "0.5.0"
25 | rand = "0.7"
26 | pairing-plus = "0.18.0"
27 | ff-zeroize="0.6.3"
28 |
--------------------------------------------------------------------------------
/cargo/src/bin.rs:
--------------------------------------------------------------------------------
1 | mod lib;
2 |
3 | use std::ffi::{CString};
4 |
5 | fn main(){
6 | let world = lib::benchmarkCode();
7 | let world_ptr = unsafe { CString::from_raw(world) };
8 | let rust_string = world_ptr.to_str().unwrap();
9 | println!("{}", rust_string);
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/cargo/src/crypto.rs:
--------------------------------------------------------------------------------
1 | use sha2::Sha512;
2 | use rand_core::{RngCore, OsRng};
3 | use curve25519_dalek::constants;
4 | use curve25519_dalek::ristretto::CompressedRistretto;
5 | use curve25519_dalek::ristretto::RistrettoPoint;
6 | use curve25519_dalek::scalar::Scalar;
7 | use std::collections::HashSet;
8 |
9 | #[derive(Debug)]
10 | pub struct ServerData {
11 | secret: Scalar,
12 | used_cards: HashSet<[u8; 32]>,
13 | pub_secret: CompressedRistretto,
14 | }
15 |
16 | #[derive(Debug)]
17 | pub struct PunchCard {
18 | card_secret: [u8; 32],
19 | punch_card: RistrettoPoint,
20 | last_mask: Scalar,
21 | count: u32,
22 | }
23 |
24 | //notation from Figure 19.7 in Boneh-Shoup textbook v0.5
25 | #[derive(Debug)]
26 | pub struct Proof {
27 | v_t: CompressedRistretto,
28 | w_t: CompressedRistretto,
29 | beta_z: [u8; 32],
30 | }
31 |
32 | fn scalar_exponentiate(base: Scalar, exp: u32) -> Scalar{
33 | if exp == 1 {
34 | base
35 | } else if exp % 2 == 1{
36 | base * scalar_exponentiate(base, exp - 1)
37 | } else {
38 | let val = scalar_exponentiate(base, exp/2);
39 | val * val
40 | }
41 | }
42 |
43 |
44 | impl ServerData {
45 |
46 | //set up the server secret and redeemed card db
47 | pub fn server_setup() -> (CompressedRistretto, ServerData) {
48 |
49 | let secret = Scalar::random(&mut OsRng);
50 | let used_cards = HashSet::new();
51 | let pub_secret = &secret * &constants::RISTRETTO_BASEPOINT_TABLE;
52 | let pub_secret = pub_secret.compress();
53 | let new_server = ServerData {
54 | secret,
55 | used_cards,
56 | pub_secret,
57 | };
58 |
59 | (pub_secret, new_server)
60 | }
61 |
62 | //punch card by multiplying by secret
63 | //prove that this was done honestly
64 | pub fn server_punch(&self, card: CompressedRistretto) -> (CompressedRistretto, Proof) {
65 |
66 | let card_dec = card.decompress().expect("couldn't decompress point in server_punch");
67 | let new_card_dec = card_dec * self.secret;
68 | let new_card = new_card_dec.compress();
69 |
70 | //generate Chaum-Pedersen proof
71 | //see Boneh Shoup textbook v0.5 Figure 19.7
72 | let beta_t = Scalar::random(&mut OsRng);
73 | let v_t = &beta_t * &constants::RISTRETTO_BASEPOINT_TABLE;
74 | let v_t_compress = v_t.compress();
75 | let w_t = card_dec * beta_t;
76 | let w_t_compress = w_t.compress();
77 |
78 | let mut hashinput: Vec = Vec::new();
79 | hashinput.extend_from_slice(&self.pub_secret.to_bytes());
80 | hashinput.extend_from_slice(&card.to_bytes());
81 | hashinput.extend_from_slice(&new_card.to_bytes());
82 | hashinput.extend_from_slice(&v_t_compress.to_bytes());
83 | hashinput.extend_from_slice(&w_t_compress.to_bytes());
84 | let hashinput_bytes: &[u8] = &hashinput;
85 | let chal = Scalar::hash_from_bytes::(hashinput_bytes);
86 | let beta_z = beta_t + self.secret * chal;
87 |
88 | let proof = Proof {
89 | v_t: v_t_compress,
90 | w_t: w_t_compress,
91 | beta_z: beta_z.to_bytes(),
92 | };
93 |
94 | (new_card, proof)
95 | }
96 |
97 | //check that the punch card is valid with num_punches
98 | //check that the punch card secret is new
99 | pub fn server_verify(&mut self, card: CompressedRistretto, card_secret: [u8; 32], num_punches: u32) -> bool {
100 |
101 | let num_punches = scalar_exponentiate(self.secret, num_punches);
102 | let expected_card = RistrettoPoint::hash_from_bytes::(&card_secret) * num_punches;
103 |
104 |
105 | if card == expected_card.compress() {
106 | //returns true if this was not in the set
107 | self.used_cards.insert(card_secret)
108 | } else {
109 | false
110 | }
111 | }
112 |
113 | pub fn count_cards(&self) -> usize {
114 | self.used_cards.len()
115 | }
116 |
117 | //preload the database of used cards with num entries
118 | pub fn cheat_setup_db(&mut self, num:u32) {
119 | for i in 0..num {
120 | let temp = Scalar::from(i).to_bytes();
121 | self.used_cards.insert(temp);
122 | }
123 | }
124 |
125 | pub fn lookup_test(&self, input: [u8; 32]) -> bool {
126 | self.used_cards.contains(&input)
127 | }
128 | }
129 |
130 |
131 | impl PunchCard {
132 |
133 | //create a new punchcard
134 | //punch card is already masked after this function
135 | pub fn card_setup() -> (CompressedRistretto, PunchCard) {
136 |
137 | let mut card_secret = [0u8; 32];
138 | OsRng.fill_bytes(&mut card_secret);
139 |
140 | let last_mask = Scalar::random(&mut OsRng);
141 |
142 | //the punch card is already masked at this point
143 | let punch_card = RistrettoPoint::hash_from_bytes::(&card_secret) * last_mask;
144 |
145 | let new_punch_card = PunchCard {
146 | card_secret,
147 | punch_card,
148 | last_mask,
149 | count: 0,
150 | };
151 |
152 | (new_punch_card.punch_card.compress(), new_punch_card)
153 | }
154 |
155 | //verify proof from the server
156 | //if accepted, unmask punchcard, remask with new mask, increment count
157 | //otherwise reuse old punchcard, same count
158 | pub fn verify_remask(&mut self, card: CompressedRistretto, pub_secret: CompressedRistretto,
159 | proof: Proof) -> (CompressedRistretto, bool) {
160 |
161 | //verify Chaum-Pedersen proof
162 | //see Boneh Shoup textbook v0.5 Figure 19.7
163 | let mut hashinput: Vec = Vec::new();
164 | hashinput.extend_from_slice(&pub_secret.to_bytes());
165 | hashinput.extend_from_slice(&self.punch_card.compress().to_bytes());
166 | hashinput.extend_from_slice(&card.to_bytes());
167 | hashinput.extend_from_slice(&proof.v_t.to_bytes());
168 | hashinput.extend_from_slice(&proof.w_t.to_bytes());
169 | let hashinput_bytes: &[u8] = &hashinput;
170 | let chal = Scalar::hash_from_bytes::(hashinput_bytes);
171 |
172 | let gbz: RistrettoPoint = &Scalar::from_bytes_mod_order(proof.beta_z) * &constants::RISTRETTO_BASEPOINT_TABLE;
173 | let vtvc = proof.v_t.decompress().expect("couldn't decompress in verify_remask")
174 | + (pub_secret.decompress().expect("couldn't decompress pub_secret in verify_remask")
175 | * chal);
176 | let ubz = self.punch_card * Scalar::from_bytes_mod_order(proof.beta_z);
177 | let wtwc = proof.w_t.decompress().expect("couldn't decompress in verify_remask")
178 | + (card.decompress().expect("couldn't decompress in verify_remask") * chal);
179 |
180 |
181 | let mut success = true;
182 | if gbz == vtvc && ubz == wtwc {
183 | //if true { //for debugging
184 | let unmasked_card = card.decompress()
185 | .expect("couldn't decompress point in verify_remask")
186 | * self.last_mask.invert();
187 | self.last_mask = Scalar::random(&mut OsRng);
188 | self.punch_card = unmasked_card * self.last_mask;
189 | self.count += 1;
190 | } else {
191 | success = false;
192 | }
193 |
194 | (self.punch_card.compress(), success)
195 | }
196 |
197 | //unmask the punch card and return its relevant contents
198 | pub fn unmask_redeem(&mut self) -> ([u8; 32], CompressedRistretto) {
199 |
200 | self.punch_card = self.punch_card * self.last_mask.invert();
201 |
202 | (self.card_secret, self.punch_card.compress())
203 | }
204 |
205 | pub fn get_count(&self) -> u32 {
206 | self.count
207 | }
208 |
209 | pub fn exp_test(&self) -> RistrettoPoint{
210 | self.punch_card * self.last_mask
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/cargo/src/crypto_pairing.rs:
--------------------------------------------------------------------------------
1 | //use sha2::Sha512;
2 | use sha2::Sha256;
3 | use rand_core::{RngCore, OsRng};
4 | use std::collections::HashSet;
5 | use curve25519_dalek::scalar::Scalar;
6 | use ff_zeroize::Field;
7 | use ff_zeroize::PrimeField;
8 | use pairing_plus::Engine;
9 | use pairing_plus::hash_to_field::ExpandMsgXmd;
10 | use pairing_plus::CurveProjective;
11 | use pairing_plus::serdes::SerDes;
12 | use pairing_plus::hash_to_field::hash_to_field;
13 | use pairing_plus::hash_to_curve::HashToCurve;
14 | use pairing_plus::bls12_381::Bls12;
15 | use pairing_plus::bls12_381::Fr;
16 | use pairing_plus::bls12_381::G1;
17 | use pairing_plus::bls12_381::G2;
18 | use pairing_plus::bls12_381::Fq12;
19 |
20 |
21 | //Making a second module with all the same functions used in crypto.rs
22 | //but for the version that uses pairings to merge 2 cards
23 | //Not the right way to do this, but it will do for now
24 |
25 | #[derive(Debug)]
26 | pub struct PairServerData {
27 | secret: Fr,
28 | used_cards: HashSet<[u8; 32]>,
29 | pub pub_secret_g1: Vec, //compressed form of g1^secret
30 | pub pub_secret_g2: Vec, //compressed form of g2^secret
31 | }
32 |
33 | //this holds the two parts of one punch card
34 | #[derive(Debug)]
35 | pub struct PairPunchCard {
36 | g1card: PairPunchCardPart,
37 | g2card: PairPunchCardPart,
38 | }
39 |
40 | //This is one punch card part
41 | #[derive(Debug)]
42 | pub struct PairPunchCardPart {
43 | card_secret: [u8; 32],
44 | punch_card: T,
45 | last_mask: Fr,
46 | count: u32,
47 | }
48 |
49 | //we'll use two proofs, one for the exponentiation in each group
50 | //notation from Figure 19.7 in Boneh-Shoup textbook v0.5
51 | #[derive(Debug)]
52 | pub struct PairProof {
53 | v_t: Vec,//compressed points in G1 or G2 (depending on proof)
54 | w_t: Vec,
55 | beta_z: Vec,//compressed point in Fr
56 | }
57 |
58 | impl PairServerData {
59 |
60 | //set up the server secret and redeemed card
61 | pub fn pair_server_setup() -> PairServerData{
62 | let secret = Fr::random(&mut OsRng);
63 | let used_cards = HashSet::new();
64 | let mut pub_secret_g1 = Vec::::new();
65 | let mut pub_secret_g2 = Vec::::new();
66 | let mut temp = G1::one();
67 | temp.mul_assign(secret);
68 | temp.serialize(&mut pub_secret_g1, true).expect("couldn't serialize");
69 | let mut temp = G2::one();
70 | temp.mul_assign(secret);
71 | temp.serialize(&mut pub_secret_g2, true).expect("couldn't serialize");
72 | let new_server = PairServerData {
73 | secret,
74 | used_cards,
75 | pub_secret_g1,
76 | pub_secret_g2,
77 | };
78 | new_server
79 | }
80 |
81 | pub fn pair_server_punch(&self, compressed_card1: &mut Vec, compressed_card2: &mut Vec) -> (Vec, Vec, PairProof, PairProof) {
82 | let dst1 = [3u8, 0u8, 0u8, 0u8];
83 | let dst2 = [4u8, 0u8, 0u8, 0u8];
84 |
85 | let (card1, proof1) = self.pair_server_punch_part::(compressed_card1, dst1);
86 | let (card2, proof2) = self.pair_server_punch_part::(compressed_card2, dst2);
87 |
88 | (card1, card2, proof1, proof2)
89 | }
90 |
91 | //this will have to be called twice, once for each piece of the card
92 | //dst is also 3,0,0,0 the first time and 4,0,0,0 the second time
93 | //punch card by multiplying by secret
94 | //prove that this was done honestly
95 | fn pair_server_punch_part(&self, compressed_card: &mut Vec, dst: [u8; 4]) -> (Vec, PairProof)
96 | where T: CurveProjective + SerDes,
97 | <::Scalar as ff_zeroize::PrimeField>::Repr: std::convert::From
98 | {
99 |
100 | let pub_secret: &[u8];
101 | if dst[0] == 3 {
102 | pub_secret = &self.pub_secret_g1;
103 | } else if dst[0] == 4 {
104 | pub_secret = &self.pub_secret_g2;
105 | } else {
106 | panic!("bad dst");
107 | }
108 |
109 | //deserialize the card given as parameter
110 | let card = T::deserialize(&mut &compressed_card[..], true).expect("couldn't deserialize");
111 | let mut new_card = card.clone();
112 | new_card.mul_assign(self.secret);
113 | let mut new_compressed_card = Vec::::new();
114 | new_card.serialize(&mut new_compressed_card, true).expect("couldn't serialize");
115 |
116 | //generate Chaum-Pedersen proof
117 | //see Boneh Shoup textbook v0.5 Figure 19.7
118 | let beta_t = Fr::random(&mut OsRng);
119 | let mut v_t = T::one();
120 | v_t.mul_assign(beta_t);
121 | let mut v_t_compressed = Vec::::new();
122 | v_t.serialize(&mut v_t_compressed, true).expect("couldn't serialize");
123 |
124 | let mut w_t = card.clone();
125 | w_t.mul_assign(beta_t);
126 | let mut w_t_compressed = Vec::::new();
127 | w_t.serialize(&mut w_t_compressed, true).expect("couldn't serialize");
128 |
129 | let mut hashinput: Vec = Vec::new();
130 | hashinput.extend_from_slice(pub_secret);
131 | hashinput.extend_from_slice(&compressed_card);
132 | hashinput.extend_from_slice(&new_compressed_card);
133 | hashinput.extend_from_slice(&v_t_compressed);
134 | hashinput.extend_from_slice(&w_t_compressed);
135 | let hashinput_bytes: &[u8] = &hashinput;
136 |
137 | let chal = hash_to_field::>(hashinput_bytes, &dst, 1)[0];
138 |
139 | let mut beta_z = chal;
140 | beta_z.mul_assign(&self.secret);
141 | beta_z.add_assign(&beta_t);
142 |
143 | let mut beta_z_compressed = Vec::::new();
144 | beta_z.serialize(&mut beta_z_compressed, true).expect("couldn't serialize");
145 |
146 | //println!("size of Fr compressed: {}", beta_z_compressed.len());//it's 32
147 | let proof = PairProof {
148 | v_t: v_t_compressed,
149 | w_t: w_t_compressed,
150 | beta_z: beta_z_compressed,
151 | };
152 |
153 | (new_compressed_card, proof)
154 |
155 | }
156 |
157 |
158 | //check that the punch card is valid with num_punches
159 | //check that the punch card secret is new
160 | pub fn pair_server_verify(&mut self, compressed_card1: &mut Vec, secret1: [u8; 32], secret2: [u8; 32], num_punches: u32) -> bool {
161 |
162 | let csuite1 = [0u8; 4];
163 | let csuite2 = [1u8, 0u8, 0u8, 0u8];
164 |
165 | //compute the values and pairings you would expect
166 | let num_punches = self.secret.pow([num_punches as u64]);
167 | let mut expcard_1_1 = >>::hash_to_curve(&secret1, &csuite1);
168 | //let expcard_1_2 = >>::hash_to_curve(&secret1, &csuite2);
169 | //let mut expcard_2_1 = >>::hash_to_curve(&secret2, &csuite1);
170 | let expcard_2_2 = >>::hash_to_curve(&secret2, &csuite2);
171 |
172 | expcard_1_1.mul_assign(num_punches);
173 | //expcard_2_1.mul_assign(num_punches);
174 |
175 | let exp_pairing_1 = Bls12::pairing(expcard_1_1, expcard_2_2);
176 | //let exp_pairing_2 = Bls12::pairing(expcard_2_1, expcard_1_2);
177 |
178 |
179 | //deserialize the cards given as parameters
180 | let card1 = Fq12::deserialize(&mut &compressed_card1[..], true).expect("couldn't deserialize");
181 | //let card2 = Fq12::deserialize(&mut &compressed_card2[..], true).expect("couldn't deserialize");
182 |
183 | //check that the card is valid (real and expected values match)
184 | if card1 == exp_pairing_1 {
185 | //check that the secrets are new
186 | //returns true if this was not in the set
187 | self.used_cards.insert(secret1) && self.used_cards.insert(secret2)
188 | } else {
189 | false
190 | }
191 | }
192 |
193 | //preload the database of used cards with num entries
194 | pub fn pair_cheat_setup_db(&mut self, num:u32) {
195 | for i in 0..num {
196 | //this is weird, but it's a hack anyway
197 | let temp = Scalar::from(i).to_bytes();
198 | self.used_cards.insert(temp);
199 | }
200 | }
201 |
202 | pub fn pair_count_cards(&self) -> usize {
203 | self.used_cards.len()
204 | }
205 |
206 | }
207 |
208 | impl PairPunchCard {
209 |
210 | //new mergable punchcard
211 | pub fn card_setup() -> (Vec, Vec, PairPunchCard) {
212 |
213 | //giving the same secret to both cards
214 | //different domain separators
215 | let mut card_secret = [0u8; 32];
216 | OsRng.fill_bytes(&mut card_secret);
217 | let csuite1 = [0u8; 4];
218 | let csuite2 = [1u8, 0u8, 0u8, 0u8];
219 |
220 | let (card1, client1) = Self::card_part_setup::(card_secret, csuite1);
221 | let (card2, client2) = Self::card_part_setup::(card_secret, csuite2);
222 |
223 | let new_card = PairPunchCard {
224 | g1card: client1,
225 | g2card: client2,
226 | };
227 |
228 | (card1, card2, new_card)
229 |
230 | }
231 |
232 | //create a new punchcard part
233 | //punch card is already masked after this function
234 | fn card_part_setup(card_secret: [u8; 32], csuite: [u8; 4]) -> (Vec, PairPunchCardPart::)
235 | where T: CurveProjective + SerDes + HashToCurve>,
236 | <::Scalar as PrimeField>::Repr: std::convert::From
237 | {
238 |
239 | let last_mask = Fr::random(&mut OsRng);
240 |
241 | let mut punch_card = >>::hash_to_curve(&card_secret, &csuite);
242 | punch_card.mul_assign(last_mask);
243 |
244 | let new_punch_card = PairPunchCardPart:: {
245 | card_secret,
246 | punch_card,
247 | last_mask,
248 | count: 0,
249 | };
250 |
251 | let mut card_compressed = Vec::::new();
252 | new_punch_card.punch_card.serialize(&mut card_compressed, true).expect("couldn't serialize");
253 |
254 | (card_compressed, new_punch_card)
255 |
256 | }
257 |
258 | pub fn verify_remask(&mut self, compressed_card1: Vec, compressed_card2: Vec, pub_secret_g1: &Vec, pub_secret_g2: &Vec, proof1: PairProof, proof2: PairProof) -> (Vec, Vec, bool) {
259 |
260 | let dst1 = [3u8, 0u8, 0u8, 0u8];
261 | let dst2 = [4u8, 0u8, 0u8, 0u8];
262 |
263 | let (card1, success1) = Self::verify_remask_part::(&mut self.g1card, compressed_card1, pub_secret_g1, proof1, dst1);
264 | let (card2, success2) = Self::verify_remask_part::(&mut self.g2card, compressed_card2, pub_secret_g2, proof2, dst2);
265 |
266 | if success1 != success2 {panic!("success values don't match");}
267 |
268 | (card1, card2, success1)
269 | }
270 |
271 | //verify proof from the server
272 | //if accepted, unmask punchcard, remask with new mask, increment count
273 | //otherwise reuse old punchcard, same count
274 | fn verify_remask_part(card: &mut PairPunchCardPart, new_compressed_card: Vec, pub_secret: &Vec, proof: PairProof, dst: [u8; 4]) -> (Vec, bool)
275 | where T: CurveProjective + SerDes,
276 | <::Scalar as ff_zeroize::PrimeField>::Repr: std::convert::From
277 | {
278 |
279 | //serialize the punch card so it can be used here
280 | let mut compressed_card = Vec::::new();
281 | card.punch_card.serialize(&mut compressed_card, true).expect("couldn't serialize");
282 |
283 | //verify Chaum-Pedersen proof
284 | //see Boneh Shoup textbook v0.5 Figure 19.7
285 | let mut hashinput: Vec = Vec::new();
286 | hashinput.extend_from_slice(pub_secret);
287 | hashinput.extend_from_slice(&compressed_card);
288 | hashinput.extend_from_slice(&new_compressed_card);
289 | hashinput.extend_from_slice(&proof.v_t);
290 | hashinput.extend_from_slice(&proof.w_t);
291 | let hashinput_bytes: &[u8] = &hashinput;
292 | let chal = hash_to_field::>(hashinput_bytes, &dst, 1)[0];
293 |
294 | //decompress proof elements and remaining inputs
295 | let pub_secret = T::deserialize(&mut &pub_secret[..], true).expect("couldn't deserialize");
296 | let v_t = T::deserialize(&mut &proof.v_t[..], true).expect("couldn't deserialize");
297 | let w_t = T::deserialize(&mut &proof.w_t[..], true).expect("couldn't deserialize");
298 | let mut new_card = T::deserialize(&mut &new_compressed_card[..], true).expect("couldn't deserialize");
299 | let beta_z = Fr::deserialize(&mut &proof.beta_z[..], true).expect("couldn't deserialize");
300 |
301 | let mut gbz = T::one();
302 | gbz.mul_assign(beta_z);
303 |
304 | let mut vtvc = v_t;
305 | let mut part = pub_secret;
306 | part.mul_assign(chal);
307 | vtvc.add_assign(&part);
308 |
309 | let mut ubz = card.punch_card;
310 | ubz.mul_assign(beta_z);
311 |
312 | let mut wtwc = w_t;
313 | let mut part = new_card;
314 | part.mul_assign(chal);
315 | wtwc.add_assign(&part);
316 |
317 | let mut success = true;
318 | if gbz == vtvc && ubz == wtwc {
319 | new_card.mul_assign(card.last_mask.inverse().expect("couldn't invert!"));
320 | card.last_mask = Fr::random(&mut OsRng);
321 | new_card.mul_assign(card.last_mask);
322 | card.punch_card = new_card;
323 | card.count += 1;
324 | } else {
325 | success = false;
326 | }
327 |
328 | //serialize new card
329 | let mut new_card_compressed = Vec::::new();
330 | new_card.serialize(&mut new_card_compressed, true).expect("couldn't serialize");
331 |
332 | (new_card_compressed, success)
333 | }
334 |
335 | //unmask the punch card, use pairings to merge, and return relevant contents
336 | pub fn pair_unmask_redeem(&mut self, mut other: PairPunchCard) -> ([u8; 32], [u8; 32], Vec) {
337 |
338 | //unmask the punch cards
339 | self.g1card.punch_card.mul_assign(self.g1card.last_mask.inverse().expect("couldn't invert!"));
340 | //self.g2card.punch_card.mul_assign(self.g2card.last_mask.inverse().expect("couldn't invert!"));
341 | //other.g1card.punch_card.mul_assign(other.g1card.last_mask.inverse().expect("couldn't invert!"));
342 | other.g2card.punch_card.mul_assign(other.g2card.last_mask.inverse().expect("couldn't invert!"));
343 |
344 | //pairings of the parts of the punch cards
345 | let pairing1 = Bls12::pairing(self.g1card.punch_card, other.g2card.punch_card);
346 | //let pairing2 = Bls12::pairing(other.g1card.punch_card, self.g2card.punch_card);
347 |
348 | //serialize pairing outputs
349 | let mut pairing1_compressed = Vec::::new();
350 | //let mut pairing2_compressed = Vec::::new();
351 | pairing1.serialize(&mut pairing1_compressed, true).expect("couldn't serialize");
352 | //pairing2.serialize(&mut pairing2_compressed, true).expect("couldn't serialize");
353 |
354 |
355 | //return the secrets from the punch cards and the results of the pairings
356 | //since both parts of each card use the same secret, we only need one from each
357 | (self.g1card.card_secret, other.g1card.card_secret, pairing1_compressed)//, pairing2_compressed)
358 | }
359 |
360 | pub fn pair_get_count(&self) -> u32 {
361 | if self.g1card.count != self.g2card.count {panic!("card counts misaligned!")}
362 |
363 | self.g1card.count
364 | }
365 |
366 | pub fn exp_test_g1(&mut self) -> G1{
367 | self.g1card.punch_card.mul_assign(self.g1card.last_mask);
368 | self.g1card.punch_card
369 | }
370 |
371 | pub fn exp_test_g2(&mut self) -> G2{
372 | self.g2card.punch_card.mul_assign(self.g2card.last_mask);
373 | self.g2card.punch_card
374 | }
375 |
376 | pub fn pair_test(&mut self) -> Fq12{
377 | Bls12::pairing(self.g1card.punch_card, self.g2card.punch_card)
378 | }
379 |
380 | }
381 |
--------------------------------------------------------------------------------
/cargo/src/lib.rs:
--------------------------------------------------------------------------------
1 | mod crypto;
2 | mod crypto_pairing;
3 |
4 | use std::os::raw::{c_char};
5 | use std::ffi::{CString};
6 | use crypto::ServerData;
7 | use crypto::PunchCard;
8 | use crypto_pairing::PairServerData;
9 | use crypto_pairing::PairPunchCard;
10 | use std::time::Instant;
11 | use curve25519_dalek::scalar::Scalar;
12 | use rand::Rng;
13 |
14 |
15 | enum Tests {
16 | Group,
17 | Lookup,
18 | Pairing,
19 | }
20 |
21 | struct Times {
22 | num_iterations: u32,
23 | num_punches: u32,
24 | setup_rows: u32,
25 | test_type: Tests,
26 | server_setup: u128,
27 | client_setup: u128,
28 | server_punch: u128,
29 | client_punch: u128,
30 | client_redeem: u128,
31 | server_redeem: u128,
32 | }
33 |
34 | #[no_mangle]
35 | pub extern fn benchmarkCode() -> *mut c_char {
36 | //call and time crypto code here
37 | //write performance numbers to the string that gets returned
38 |
39 |
40 |
41 | let mut times = Times {
42 | num_iterations: 1000, //how many iterations to average over
43 | num_punches: 10, //how many punches before a card is redeemed, must be even for the pairing version test code
44 | setup_rows: 0, //change to larger number to test with used cards in db, also make this larger for the lookup test (or else it will crash)
45 | test_type: Tests::Group,
46 | server_setup: 0,
47 | client_setup: 0,
48 | server_punch: 0,
49 | client_punch: 0,
50 | client_redeem: 0,
51 | server_redeem: 0,
52 | };
53 |
54 | let perf_string: &str;
55 |
56 | match times.test_type {
57 | Tests::Group => {
58 | for _ in 0..times.num_iterations {
59 | //if j % 10 == 0 {println!("10 more done!\n");}
60 |
61 | //set up server
62 | let now = Instant::now();
63 | let (pub_secret, mut server) = ServerData::server_setup();
64 | let elapsed = now.elapsed().as_micros();
65 | //println!("time elapsed in server setup: {}", elapsed);
66 | times.server_setup += elapsed;
67 |
68 | //fill up database of used cards
69 | server.cheat_setup_db(times.setup_rows);
70 |
71 | //println!("number of used punchcards: {}", server.count_cards());
72 |
73 | //create new punchcard
74 | let now = Instant::now();
75 | let (mut current_card, mut client) = PunchCard::card_setup();
76 | let elapsed = now.elapsed().as_micros();
77 | //println!("time elapsed in punchcard setup: {}", elapsed);
78 | times.client_setup += elapsed;
79 |
80 |
81 | //punch the card
82 | for i in 0..times.num_punches {
83 |
84 | //server punches
85 | let now = Instant::now();
86 | let (new_card, proof) = server.server_punch(current_card);
87 | let elapsed = now.elapsed().as_micros();
88 | //println!("time elapsed in server punch: {}", elapsed);
89 | times.server_punch += elapsed;
90 |
91 | //client verifies punch, prepares for next punch
92 | let now = Instant::now();
93 | let res = client.verify_remask(new_card, pub_secret, proof);
94 | current_card = res.0;
95 | let punch_success = res.1;
96 | let elapsed = now.elapsed().as_micros();
97 | if !punch_success {panic!("punch failed");}
98 | //println!("time elapsed in client punch: {}", elapsed);
99 | times.client_punch += elapsed;
100 |
101 | //println!("punch succeeded? {}", punch_success);
102 | //println!("punch count: {}", client.get_count());
103 | if client.get_count() != i+1 {panic!("punch count wrong");}
104 | }
105 |
106 |
107 | //client redeems card
108 | let now = Instant::now();
109 | let (card_secret, final_card) = client.unmask_redeem();
110 | let elapsed = now.elapsed().as_micros();
111 | //println!("time elapsed in redemption (client): {}", elapsed);
112 | times.client_redeem += elapsed;
113 |
114 | //server verifies card
115 | let now = Instant::now();
116 | let redeem_success = server.server_verify(final_card, card_secret, times.num_punches);
117 | if !redeem_success {panic!("redemption failed");}
118 | let elapsed = now.elapsed().as_micros();
119 | //println!("time elapsed in redemption (server): {}", elapsed);
120 | times.server_redeem += elapsed;
121 |
122 | //println!("card redemption succeeded? {}", redeem_success);
123 | //println!("number of used punchcards: {}", server.count_cards());
124 | if server.count_cards() != (times.setup_rows + 1) as usize {panic!("wrong number of rows in card database");}
125 |
126 | }
127 |
128 | perf_string = "Performance Results for 25519 group\n";
129 | },
130 | Tests::Lookup => {
131 | //mostly using this as scratch space for miscellaneous experiments
132 | let (_, mut server) = ServerData::server_setup();
133 | server.cheat_setup_db(times.setup_rows);
134 | let (_, client) = PunchCard::card_setup();
135 | let mut rng = rand::thread_rng();
136 |
137 | let (_, _, mut pairing_client) = PairPunchCard::card_setup();
138 |
139 | for _ in 0..times.num_iterations {
140 | let x:u32 = rng.gen_range(0, times.setup_rows);
141 | let val = Scalar::from(x).to_bytes();
142 |
143 |
144 | let now = Instant::now();
145 | let there = server.lookup_test(val);
146 | let elapsed = now.elapsed().as_nanos();
147 | //println!("time elapsed in redemption (server): {}", elapsed);
148 | times.server_setup += elapsed;
149 | if !there {panic!("wasn't there!");}
150 |
151 |
152 | let now = Instant::now();
153 | let _res = client.exp_test();
154 | let elapsed = now.elapsed().as_micros();
155 | times.client_setup += elapsed;
156 |
157 |
158 |
159 | let now = Instant::now();
160 | let _res = pairing_client.exp_test_g1();
161 | let elapsed = now.elapsed().as_micros();
162 | times.client_redeem += elapsed;
163 |
164 | let now = Instant::now();
165 | let _res = pairing_client.exp_test_g2();
166 | let elapsed = now.elapsed().as_micros();
167 | times.server_redeem += elapsed;
168 |
169 | let now = Instant::now();
170 | let _res = pairing_client.pair_test();
171 | let elapsed = now.elapsed().as_micros();
172 | times.server_punch += elapsed;
173 | }
174 |
175 | perf_string = "Performance Results for misc experiment\n";
176 | },
177 | Tests::Pairing => {
178 | //similar to the group code above, but for the pairing version
179 | //we will create 2 cards and punch each 5 times, then merge them to redeem
180 | for j in 0..times.num_iterations {
181 | if j % 10 == 0 {println!("10 more done!\n");}
182 |
183 | //set up server
184 | let now = Instant::now();
185 | let mut server = PairServerData::pair_server_setup();
186 | let elapsed = now.elapsed().as_micros();
187 | //println!("time elapsed in server setup: {}", elapsed);
188 | times.server_setup += elapsed;
189 |
190 | //fill up database of used cards
191 | //double because each card is actually 2 cards
192 | server.pair_cheat_setup_db(2*times.setup_rows);
193 |
194 | //println!("number of used punchcards: {}", server.count_cards());
195 |
196 | //create new punchcard
197 | let now = Instant::now();
198 | let (mut current_card_g1, mut current_card_g2, mut client) = PairPunchCard::card_setup();
199 | let elapsed = now.elapsed().as_micros();
200 | //println!("time elapsed in punchcard setup: {}", elapsed);
201 | times.client_setup += elapsed;
202 |
203 | //create a second card that's going to be merged with the first
204 | let (mut second_current_card_g1, mut second_current_card_g2, mut second_client) = PairPunchCard::card_setup();
205 |
206 |
207 | //punch the first card
208 | for i in 0..times.num_punches/2 {
209 |
210 | //server punches
211 | let now = Instant::now();
212 | let (new_card_g1, new_card_g2, proof_g1, proof_g2) = server.pair_server_punch(&mut current_card_g1, &mut current_card_g2);
213 | let elapsed = now.elapsed().as_micros();
214 | //println!("time elapsed in server punch: {}", elapsed);
215 | times.server_punch += elapsed;
216 |
217 | //client verifies punch, prepares for next punch
218 | let now = Instant::now();
219 | let res = client.verify_remask(new_card_g1, new_card_g2, &server.pub_secret_g1, &server.pub_secret_g2, proof_g1, proof_g2);
220 | current_card_g1 = res.0;
221 | current_card_g2 = res.1;
222 | let punch_success = res.2;
223 | let elapsed = now.elapsed().as_micros();
224 | if !punch_success {panic!("punch failed");}
225 | //println!("time elapsed in client punch: {}", elapsed);
226 | times.client_punch += elapsed;
227 |
228 | //println!("punch succeeded? {}", punch_success);
229 | //println!("punch count: {}", client.get_count());
230 | if client.pair_get_count() != i+1 {panic!("first punch count wrong");}
231 | }
232 | //punch the second card
233 | for i in 0..times.num_punches/2 {
234 |
235 | //server punches
236 | let now = Instant::now();
237 | let (new_card_g1, new_card_g2, proof_g1, proof_g2) = server.pair_server_punch(&mut second_current_card_g1, &mut second_current_card_g2);
238 | let elapsed = now.elapsed().as_micros();
239 | //println!("time elapsed in server punch: {}", elapsed);
240 | times.server_punch += elapsed;
241 |
242 | //client verifies punch, prepares for next punch
243 | let now = Instant::now();
244 | let res = second_client.verify_remask(new_card_g1, new_card_g2, &server.pub_secret_g1, &server.pub_secret_g2, proof_g1, proof_g2);
245 | second_current_card_g1 = res.0;
246 | second_current_card_g2 = res.1;
247 | let punch_success = res.2;
248 | let elapsed = now.elapsed().as_micros();
249 | if !punch_success {panic!("punch failed");}
250 | //println!("time elapsed in client punch: {}", elapsed);
251 | times.client_punch += elapsed;
252 |
253 | //println!("punch succeeded? {}", punch_success);
254 | //println!("punch count: {}", client.get_count());
255 | if second_client.pair_get_count() != i+1 {panic!("second punch count wrong");}
256 | }
257 |
258 |
259 | //client redeems card
260 | let now = Instant::now();
261 | let (card_secret, second_card_secret, mut final_card) = client.pair_unmask_redeem(second_client);
262 | let elapsed = now.elapsed().as_micros();
263 | //println!("time elapsed in redemption (client): {}", elapsed);
264 | times.client_redeem += elapsed;
265 |
266 | //server verifies card
267 | let now = Instant::now();
268 | let redeem_success = server.pair_server_verify(&mut final_card, card_secret, second_card_secret, times.num_punches);
269 | if !redeem_success {panic!("redemption failed");}
270 | let elapsed = now.elapsed().as_micros();
271 | //println!("time elapsed in redemption (server): {}", elapsed);
272 | times.server_redeem += elapsed;
273 |
274 | //println!("card redemption succeeded? {}", redeem_success);
275 | //println!("number of used punchcards: {}", server.count_cards());
276 | if server.pair_count_cards() != (2*times.setup_rows + 2) as usize {panic!("wrong number of rows in card database");}
277 |
278 | }
279 |
280 | perf_string = "Performance Results for BLS12_381 group with merging\n";
281 |
282 |
283 | },
284 | }
285 |
286 |
287 |
288 |
289 |
290 | let perf_string = perf_string.to_owned() +
291 | &"Each operation is repeated for ".to_owned()
292 | + ×.num_iterations.to_string().to_owned() +
293 | &" iterations, except punches, which are done ".to_owned()
294 | + &(times.num_iterations*times.num_punches).to_string().to_owned() +
295 | &" times (".to_owned()
296 | + ×.num_punches.to_string().to_owned() +
297 | &" punches per iteration). \nThe server database starts with ".to_owned()
298 | + ×.setup_rows.to_string().to_owned() +
299 | &" used punchcards in each iteration.".to_owned() +
300 | &" \nNumbers are cumulative over all runs, in microseconds.\n".to_owned() +
301 | &"Server setup: ".to_owned() + ×.server_setup.to_string().to_owned() +
302 | &"\nClient setup: ".to_owned() + ×.client_setup.to_string().to_owned() +
303 | &"\nServer punch: ".to_owned() + ×.server_punch.to_string().to_owned() +
304 | &"\nClient punch: ".to_owned() + ×.client_punch.to_string().to_owned() +
305 | &"\nClient redeem: ".to_owned() + ×.client_redeem.to_string().to_owned() +
306 | &"\nServer redeem: ".to_owned() + ×.server_redeem.to_string().to_owned() +
307 | &"\n".to_owned();
308 |
309 | CString::new(perf_string.to_owned()).unwrap().into_raw()
310 | }
311 |
312 | /// Expose the JNI interface for android below
313 | #[cfg(target_os="android")]
314 | #[allow(non_snake_case)]
315 | pub mod android {
316 | extern crate jni;
317 |
318 | use super::*;
319 | use self::jni::JNIEnv;
320 | use self::jni::objects::{JClass};
321 | use self::jni::sys::{jstring};
322 |
323 | #[no_mangle]
324 | pub unsafe extern fn Java_com_example_punchcard_RustPunchCard_benchmarkCode(env: JNIEnv, _: JClass) -> jstring {
325 | // Our Java companion code might pass-in "world" as a string, hence the name.
326 | let world = benchmarkCode();
327 | // Retake pointer so that we can use it below and allow memory to be freed when it goes out of scope.
328 | let world_ptr = CString::from_raw(world);
329 | let output = env.new_string(world_ptr.to_str().unwrap()).expect("Couldn't create java string!");
330 |
331 | output.into_inner()
332 | }
333 | }
334 |
335 |
--------------------------------------------------------------------------------
/cargo/src/lib/crypto.rs:
--------------------------------------------------------------------------------
1 | ../crypto.rs
--------------------------------------------------------------------------------
/cargo/src/lib/crypto_pairing.rs:
--------------------------------------------------------------------------------
1 | ../crypto_pairing.rs
--------------------------------------------------------------------------------
/data.txt:
--------------------------------------------------------------------------------
1 | Punch card scheme with curve25519-dalek
2 |
3 | Performance Results (computer)
4 | Each operation is repeated for 1000 iterations, except punches, which are done 10000 times (10 punches per iteration).
5 | The server database starts with 0 used punchcards in each iteration.
6 | Numbers are cumulative over all runs, in microseconds.
7 | Server setup: 18590
8 | Client setup: 65722
9 | Server punch: 1343669
10 | Client punch: 3123742
11 | Client redeem: 65837
12 | Server redeem: 64278
13 |
14 | so the averages are (in microseconds):
15 | Server setup: 18.590
16 | Client setup: 65.722
17 | Server punch: 134.3669
18 | Client punch: 312.3742
19 | Client redeem: 65.837
20 | Server redeem: 64.278
21 |
22 | When I increased the starting database size to 1M, I got these numbers
23 | Server setup: 27371
24 | Client setup: 85662
25 | Server punch: 1562951
26 | Client punch: 3497363
27 | Client redeem: 73585
28 | Server redeem: 72136
29 | The only one whose performance should be affected by the database size is server redeem, but it does not look different relative to the other numbers (the results are generally high variance). This is not surprising because the only DB-dependent operation is the hash table lookup.
30 |
31 |
32 | Performance Results (Google Pixel)
33 | Each operation is repeated for 1000 iterations, except punches, which are done 10000 times (10 punches per iteration).
34 | The server database starts with 0 used punchcards in each iteration.
35 | Numbers are cumulative over all runs, in microseconds.
36 | Server setup: 304114
37 | Client setup: 939123
38 | Server punch: 19388147
39 | Client punch: 43142327
40 | Client redeem: 889866
41 | Server redeem: 949928
42 |
43 | so the averages are (in microseconds):
44 | Server setup: 304.114
45 | Client setup: 939.123
46 | Server punch: 1938.8147
47 | Client punch: 4314.2327
48 | Client redeem: 889.866
49 | Server redeem: 949.928
50 |
51 |
52 | Communication costs (for messages sent in protocol)
53 | Server setup: 32 bytes (g^secret)
54 | Client setup: none
55 | Client punch: 32 bytes (the punchcard group element)
56 | Server punch: 128 bytes (new group element and proof which has 2 group elements and a scalar, 32 bytes each)
57 | Client redeem: 64 bytes (the final card and the secret used to make the card, 32 bytes each)
58 | Server redeem: none
59 |
60 | On server,
61 | Time for lookup in hashset of 1 million entries is <1 microsecond (about .2-.3 microseconds)
62 | Time for exponentiation is about 50 microseconds (usually between 50 and 55)
63 | so to do 1M exponentiations (one for each previously used card) would probably be about 50 seconds. The speedup is about 8 orders of magnitude.
64 |
65 | Punch card scheme with pairing-plus (BLS12-381)
66 |
67 | Performance Results for BLS12_381 group with merging (computer)
68 | Each operation is repeated for 100 iterations, except punches, which are done 1000 times (10 punches per iteration).
69 | The server database starts with 0 used punchcards in each iteration.
70 | Numbers are cumulative over all runs, in microseconds.
71 | Server setup: 109839
72 | Client setup: 278976
73 | Server punch: 4327845
74 | Client punch: 10851089
75 | Client redeem: 305215
76 | Server redeem: 400271
77 |
78 | so the averages are (in _milliseconds_):
79 | Server setup: 1.09
80 | Client setup: 2.79
81 | Server punch: 4.33
82 | Client punch: 10.85
83 | Client redeem: 3.05
84 | Server redeem: 4.00
85 |
86 | Performance Results for BLS12_381 group with merging (Google Pixel)
87 | Each operation is repeated for 100 iterations, except punches, which are done 1000 times (10 punches per iteration).
88 | The server database starts with 0 used punchcards in each iteration.
89 | Numbers are cumulative over all runs, in microseconds.
90 | Server setup: 1332493
91 | Client setup: 3496631
92 | Server punch: 54449731
93 | Client punch: 137793866
94 | Client redeem: 3643494
95 | Server redeem: 4810848
96 |
97 | so the averages are (in _milliseconds_):
98 | Server setup: 13.32
99 | Client setup: 34.97
100 | Server punch: 54.45
101 | Client punch: 137.79
102 | Client redeem: 36.43
103 | Server redeem: 48.11
104 |
105 | Communication costs (for messages sent in protocol)
106 | Server setup: 144 bytes (g^secret for both groups == 48 + 96)
107 | Client setup: none
108 | Client punch: 144 bytes (the 2 punchcard group elements)
109 | Server punch: 496 bytes (2 new group elements and 2 proofs which have 2 group elements and a scalar = 144 + (96 + 32) + (192 + 32) = 496)
110 | Client redeem: 640 bytes (the final card and the secrets used to make the cards, 32 bytes each secret, 576 bytes for final card)
111 | Server redeem: none
112 |
113 | On server,
114 | Time for exponentiation in G1 is about 250 microseconds
115 | Time for exponentiation in G2 is aobut 800 microseconds
116 | Time for pairing is about 2 milliseconds
117 |
--------------------------------------------------------------------------------