├── .gitignore ├── .gradle ├── 3.5-rc-2 │ ├── file-changes │ │ └── last-build.bin │ └── taskHistory │ │ ├── fileHashes.bin │ │ ├── fileSnapshots.bin │ │ ├── taskHistory.bin │ │ └── taskHistory.lock └── buildOutputCleanup │ ├── built.bin │ ├── cache.properties │ └── cache.properties.lock ├── .idea ├── .name ├── compiler.xml ├── inspectionProfiles │ └── Project_Default.xml ├── misc.xml ├── modules.xml ├── modules │ ├── BLS Signature Aggregation.iml │ ├── BLS_Signature_Aggregation.iml │ ├── BLS_Signature_Aggregation_main.iml │ └── BLS_Signature_Aggregation_test.iml └── vcs.xml ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── main ├── java │ ├── com │ │ └── gazman │ │ │ └── bls │ │ │ ├── BlsSignatures.java │ │ │ ├── model │ │ │ ├── BlsModel.java │ │ │ └── Signature.java │ │ │ └── utils │ │ │ ├── RandomHolder.java │ │ │ └── Sha256Hash.java │ └── it │ │ └── unisa │ │ └── dia │ │ └── gas │ │ ├── jpbc │ │ ├── Element.java │ │ ├── ElementPow.java │ │ ├── ElementPowPreProcessing.java │ │ ├── Field.java │ │ ├── FieldOver.java │ │ ├── Pairing.java │ │ ├── PairingParameters.java │ │ ├── PairingParametersGenerator.java │ │ ├── PairingPreProcessing.java │ │ ├── Point.java │ │ ├── Polynomial.java │ │ └── Vector.java │ │ └── plaf │ │ └── jpbc │ │ ├── field │ │ ├── base │ │ │ ├── AbstractElement.java │ │ │ ├── AbstractElementPowPreProcessing.java │ │ │ ├── AbstractField.java │ │ │ ├── AbstractFieldOver.java │ │ │ ├── AbstractPointElement.java │ │ │ └── AbstractVectorElement.java │ │ ├── curve │ │ │ ├── CurveElement.java │ │ │ ├── CurveField.java │ │ │ └── ImmutableCurveElement.java │ │ ├── gt │ │ │ ├── GTFiniteElement.java │ │ │ ├── GTFiniteField.java │ │ │ └── ImmutableGTFiniteElement.java │ │ ├── poly │ │ │ ├── AbstractPolyElement.java │ │ │ ├── ImmutablePolyModElement.java │ │ │ ├── PolyElement.java │ │ │ ├── PolyField.java │ │ │ ├── PolyModElement.java │ │ │ ├── PolyModField.java │ │ │ └── PolyUtils.java │ │ ├── quadratic │ │ │ ├── DegreeTwoExtensionQuadraticElement.java │ │ │ ├── DegreeTwoExtensionQuadraticField.java │ │ │ ├── ImmutableDegreeTwoExtensionQuadraticElement.java │ │ │ ├── ImmutableQuadraticElement.java │ │ │ ├── QuadraticElement.java │ │ │ └── QuadraticField.java │ │ ├── vector │ │ │ ├── ImmutableVectorElement.java │ │ │ ├── VectorElement.java │ │ │ ├── VectorElementPowPreProcessing.java │ │ │ └── VectorField.java │ │ └── z │ │ │ ├── AbstractZElement.java │ │ │ ├── ImmutableZrElement.java │ │ │ ├── SymmetricZrElement.java │ │ │ ├── SymmetricZrField.java │ │ │ ├── ZElement.java │ │ │ ├── ZField.java │ │ │ ├── ZrElement.java │ │ │ └── ZrField.java │ │ ├── pairing │ │ ├── AbstractPairing.java │ │ ├── PairingFactory.java │ │ ├── a │ │ │ ├── TypeACurveGenerator.java │ │ │ ├── TypeAPairing.java │ │ │ ├── TypeATateAffineMillerPairingMap.java │ │ │ ├── TypeATateNafProjectiveMillerPairingMap.java │ │ │ └── TypeATateProjectiveMillerPairingMap.java │ │ ├── a1 │ │ │ ├── TypeA1CurveGenerator.java │ │ │ ├── TypeA1Pairing.java │ │ │ ├── TypeA1TateAffineMillerPairingMap.java │ │ │ └── TypeA1TateNafProjectiveMillerPairingMap.java │ │ ├── accumulator │ │ │ ├── AbstractPairingAccumulator.java │ │ │ ├── MultiThreadedMulPairingAccumulator.java │ │ │ ├── PairingAccumulator.java │ │ │ ├── PairingAccumulatorFactory.java │ │ │ └── SequentialMulPairingAccumulator.java │ │ ├── d │ │ │ ├── TypeDPairing.java │ │ │ └── TypeDTateAffineNoDenomMillerPairingMap.java │ │ ├── e │ │ │ ├── TypeECurveGenerator.java │ │ │ ├── TypeEPairing.java │ │ │ └── TypeETateProjectiveMillerPairingMap.java │ │ ├── f │ │ │ ├── TypeFPairing.java │ │ │ └── TypeFTateNoDenomMillerPairingMap.java │ │ ├── g │ │ │ ├── TypeGPairing.java │ │ │ └── TypeGTateAffineNoDenomMillerPairingMap.java │ │ ├── immutable │ │ │ ├── ImmutableElementPowPreProcessing.java │ │ │ ├── ImmutableField.java │ │ │ ├── ImmutablePairingPreProcessing.java │ │ │ └── ImmutableParing.java │ │ ├── map │ │ │ ├── AbstractMillerPairingMap.java │ │ │ ├── AbstractMillerPairingPreProcessing.java │ │ │ ├── AbstractPairingMap.java │ │ │ ├── DefaultPairingPreProcessing.java │ │ │ └── PairingMap.java │ │ └── parameters │ │ │ ├── MutablePairingParameters.java │ │ │ └── PropertiesParameters.java │ │ └── util │ │ ├── Arrays.java │ │ ├── ElementUtils.java │ │ ├── concurrent │ │ ├── ExecutorServiceUtils.java │ │ ├── Pool.java │ │ ├── PoolExecutor.java │ │ ├── accumultor │ │ │ ├── AbstractAccumulator.java │ │ │ └── Accumulator.java │ │ ├── context │ │ │ ├── ContextExecutor.java │ │ │ └── ContextRunnable.java │ │ └── recursive │ │ │ └── RecursiveMultiplier.java │ │ ├── io │ │ ├── Base64.java │ │ ├── ExByteArrayInputStream.java │ │ ├── FieldStreamReader.java │ │ └── PairingStreamReader.java │ │ └── math │ │ └── BigIntegerUtils.java └── resources │ └── it │ └── unisa │ └── dia │ └── gas │ └── plaf │ └── jpbc │ └── pairing │ ├── a │ └── a_181_603.properties │ ├── a1 │ ├── a1.properties │ └── a1_3primes.properties │ ├── d │ └── d_9563.properties │ ├── e │ └── e.properties │ ├── f │ └── f.properties │ └── g │ └── g149.properties └── test └── java └── com └── gazman └── bls └── BlsSignaturesTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.ear 19 | *.zip 20 | *.tar.gz 21 | *.rar 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | ### JetBrains template 26 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 27 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 28 | 29 | # User-specific stuff: 30 | .idea/**/workspace.xml 31 | .idea/**/tasks.xml 32 | .idea/dictionaries 33 | 34 | # Sensitive or high-churn files: 35 | .idea/**/dataSources/ 36 | .idea/**/dataSources.ids 37 | .idea/**/dataSources.xml 38 | .idea/**/dataSources.local.xml 39 | .idea/**/sqlDataSources.xml 40 | .idea/**/dynamic.xml 41 | .idea/**/uiDesigner.xml 42 | 43 | # Gradle: 44 | .idea/**/gradle.xml 45 | .idea/**/libraries 46 | 47 | # CMake 48 | cmake-build-debug/ 49 | 50 | # Mongo Explorer plugin: 51 | .idea/**/mongoSettings.xml 52 | 53 | ## File-based project format: 54 | *.iws 55 | 56 | ## Plugin-specific files: 57 | 58 | # IntelliJ 59 | out/ 60 | 61 | # mpeltonen/sbt-idea plugin 62 | .idea_modules/ 63 | 64 | # JIRA plugin 65 | atlassian-ide-plugin.xml 66 | 67 | # Cursive Clojure plugin 68 | .idea/replstate.xml 69 | 70 | # Crashlytics plugin (for Android Studio and IntelliJ) 71 | com_crashlytics_export_strings.xml 72 | crashlytics.properties 73 | crashlytics-build.properties 74 | fabric.properties 75 | 76 | -------------------------------------------------------------------------------- /.gradle/3.5-rc-2/file-changes/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/3.5-rc-2/taskHistory/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gazman-sdk/BLS_signature_aggregation/4a2bc5d5a1fe7c3da44271297825c6679099c8b5/.gradle/3.5-rc-2/taskHistory/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/3.5-rc-2/taskHistory/fileSnapshots.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gazman-sdk/BLS_signature_aggregation/4a2bc5d5a1fe7c3da44271297825c6679099c8b5/.gradle/3.5-rc-2/taskHistory/fileSnapshots.bin -------------------------------------------------------------------------------- /.gradle/3.5-rc-2/taskHistory/taskHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gazman-sdk/BLS_signature_aggregation/4a2bc5d5a1fe7c3da44271297825c6679099c8b5/.gradle/3.5-rc-2/taskHistory/taskHistory.bin -------------------------------------------------------------------------------- /.gradle/3.5-rc-2/taskHistory/taskHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gazman-sdk/BLS_signature_aggregation/4a2bc5d5a1fe7c3da44271297825c6679099c8b5/.gradle/3.5-rc-2/taskHistory/taskHistory.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/built.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gazman-sdk/BLS_signature_aggregation/4a2bc5d5a1fe7c3da44271297825c6679099c8b5/.gradle/buildOutputCleanup/built.bin -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Sat Feb 03 10:25:53 EST 2018 2 | gradle.version=3.5-rc-2 3 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties.lock: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | BLS Signature Aggregation -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 38 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/modules/BLS Signature Aggregation.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/modules/BLS_Signature_Aggregation.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/modules/BLS_Signature_Aggregation_main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/modules/BLS_Signature_Aggregation_test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BLS_signature_aggregation 2 | Java Boneh, Lynn, and Shacham (BLS) Signature Aggregation. 3 | Implementation of "Aggregate and Verifiably Encrypted Signatures from Bilinear Maps" by Dan Boneh, Ben Lynn, Craig Gentry and Hovav Shacham. 4 | https://crypto.stanford.edu/~dabo/pubs/papers/aggreg.pdf 5 | 6 | This project is built on top of JPBC - http://gas.dia.unisa.it/projects/jpbc/index.html#.WnYubqinGCo 7 | 8 | # What been changed 9 | Most of the JPBC code, not needed for this project, been removed, minor fixes have been applied, like null checks, simplification of if statements, method inlinement, and removal of redundant code 10 | 11 | 12 | # How to install 13 | Create new project from this GitHub repo using IntelliJ 14 | 15 | # How to run 16 | Run the unit tests 17 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | group 'gazman' 2 | version '1.0-SNAPSHOT' 3 | 4 | apply plugin: 'java' 5 | 6 | sourceCompatibility = 1.8 7 | 8 | repositories { 9 | mavenCentral() 10 | } 11 | 12 | dependencies { 13 | testCompile group: 'junit', name: 'junit', version: '4.12' 14 | } 15 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Feb 03 10:25:53 EST 2018 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-3.5-rc-2-bin.zip 7 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'BLS Signature Aggregation' 2 | 3 | -------------------------------------------------------------------------------- /src/main/java/com/gazman/bls/BlsSignatures.java: -------------------------------------------------------------------------------- 1 | package com.gazman.bls; 2 | 3 | import com.gazman.bls.model.BlsModel; 4 | import com.gazman.bls.model.Signature; 5 | import com.gazman.bls.utils.Sha256Hash; 6 | import it.unisa.dia.gas.jpbc.Element; 7 | import it.unisa.dia.gas.jpbc.Pairing; 8 | 9 | import java.nio.ByteBuffer; 10 | import java.util.ArrayList; 11 | 12 | /** 13 | * Created by Ilya Gazman on 2/3/2018. 14 | */ 15 | public class BlsSignatures { 16 | 17 | private Pairing pairing = BlsModel.instance.pairing; 18 | private Element systemParameters = BlsModel.instance.systemParameters; 19 | private ArrayList signatures = new ArrayList<>(); 20 | 21 | public Signature sign(byte[] message, byte[] privateKey) { 22 | Element secretKey = pairing.getZr().newElementFromBytes(privateKey); 23 | Element publicKey = systemParameters.duplicate().powZn(secretKey); 24 | 25 | 26 | byte[] hash = hash(message, publicKey); 27 | Element h = pairing.getG1().newElementFromHash(hash, 0, hash.length); 28 | 29 | Element signatureElement = h.powZn(secretKey); 30 | 31 | Signature signature = new Signature(); 32 | signature.message = message; 33 | signature.publicKey = publicKey; 34 | signature.signature = signatureElement; 35 | return signature; 36 | } 37 | 38 | public void addSignature(Signature signature) { 39 | signatures.add(signature); 40 | } 41 | 42 | public boolean validate() { 43 | Element compactSignature = signatures.get(0).signature.duplicate(); 44 | for (int i = 1; i < signatures.size(); i++) { 45 | compactSignature = compactSignature.mul(signatures.get(i).signature); 46 | } 47 | Element compactPairing = pairing.pairing(compactSignature, systemParameters.duplicate()); 48 | 49 | byte[] hash0 = hash(signatures.get(0).message, signatures.get(0).publicKey); 50 | Element hashElement0 = pairing.getG1().newElementFromHash(hash0, 0, hash0.length); 51 | Element fullPairing = pairing.pairing(hashElement0, signatures.get(0).publicKey); 52 | for (int i = 1; i < signatures.size(); i++) { 53 | byte[] messageHash = hash(signatures.get(i).message, signatures.get(i).publicKey); 54 | 55 | Element hashElement = pairing.getG1().newElementFromHash(messageHash, 0, messageHash.length); 56 | Element publicKey = signatures.get(i).publicKey; 57 | Element p = pairing.pairing(hashElement, publicKey); 58 | fullPairing.mul(p); 59 | } 60 | 61 | return compactPairing.isEqual(fullPairing); 62 | } 63 | 64 | private byte[] hash(byte[] message, Element publicKey) { 65 | byte[] bytes1 = Sha256Hash.hash(message); 66 | byte[] bytes2 = publicKey.toBytes(); 67 | ByteBuffer buffer = ByteBuffer.allocate(bytes1.length + bytes2.length); 68 | buffer.put(bytes1); 69 | buffer.put(bytes2); 70 | 71 | return Sha256Hash.hash(buffer.array()); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/gazman/bls/model/BlsModel.java: -------------------------------------------------------------------------------- 1 | package com.gazman.bls.model; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Pairing; 5 | import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory; 6 | 7 | /** 8 | * Created by Ilya Gazman on 2/3/2018. 9 | */ 10 | public enum BlsModel { 11 | instance; 12 | 13 | public final Pairing pairing; 14 | public final Element systemParameters; 15 | 16 | BlsModel(){ 17 | pairing = PairingFactory.getPairing("it/unisa/dia/gas/plaf/jpbc/pairing/a/a_181_603.properties"); 18 | systemParameters = pairing.getG2().newRandomElement(); // this will be a hardcoded value in the future 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/gazman/bls/model/Signature.java: -------------------------------------------------------------------------------- 1 | package com.gazman.bls.model; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | /** 6 | * Created by Ilya Gazman on 2/3/2018. 7 | */ 8 | public class Signature { 9 | public byte[] message; 10 | public Element publicKey; 11 | public Element signature; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/gazman/bls/utils/RandomHolder.java: -------------------------------------------------------------------------------- 1 | package com.gazman.bls.utils; 2 | 3 | import java.security.NoSuchAlgorithmException; 4 | import java.security.SecureRandom; 5 | 6 | /** 7 | * Created by Ilya Gazman on 2/3/2018. 8 | */ 9 | public class RandomHolder { 10 | public static final SecureRandom RANDOM; 11 | static { 12 | SecureRandom random; 13 | try { 14 | random = SecureRandom.getInstanceStrong(); 15 | } catch (NoSuchAlgorithmException e) { 16 | random = new SecureRandom(); 17 | e.printStackTrace(); 18 | } 19 | RANDOM = random; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/gazman/bls/utils/Sha256Hash.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Google Inc. 3 | * Copyright 2014 Andreas Schildbach 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.gazman.bls.utils; 19 | 20 | import java.nio.charset.Charset; 21 | import java.security.MessageDigest; 22 | import java.security.NoSuchAlgorithmException; 23 | 24 | public class Sha256Hash { 25 | 26 | private static final MessageDigest DIGEST; 27 | public static final Charset UTF_8 = Charset.forName("UTF-8"); 28 | 29 | static { 30 | try { 31 | DIGEST = MessageDigest.getInstance("SHA-256"); 32 | } catch (NoSuchAlgorithmException e) { 33 | throw new Error(e); 34 | } 35 | } 36 | 37 | public static synchronized byte[] hash(byte[] data){ 38 | return DIGEST.digest(data); 39 | } 40 | 41 | public static synchronized byte[] hash(byte[] data, int offset, int length){ 42 | DIGEST.update(data, offset, length); 43 | return DIGEST.digest(); 44 | } 45 | 46 | public static synchronized byte[] hash(String data){ 47 | return hash(data.getBytes(UTF_8)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/ElementPow.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * Common interface for the exponentiation. 7 | * 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | * @since 1.2.0 10 | */ 11 | public interface ElementPow { 12 | 13 | /** 14 | * Compute the power to n. 15 | * 16 | * @param n the exponent of the power. 17 | * @return the computed power. 18 | * @since 1.2.0 19 | */ 20 | Element pow(BigInteger n); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/ElementPowPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | * @since 1.0.0 8 | */ 9 | public interface ElementPowPreProcessing extends ElementPow { 10 | 11 | /** 12 | * Returns the field the pre-processed element belongs to. 13 | * 14 | * @return Returns the field the pre-processed element belongs to. 15 | * @since 1.2.0 16 | */ 17 | Field getField(); 18 | 19 | /** 20 | * Compute the power to n using the pre-processed information. 21 | * 22 | * @param n the exponent of the power. 23 | * @return a new element whose value is the computed power. 24 | * @since 1.0.0 25 | */ 26 | Element pow(BigInteger n); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/Field.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | import java.math.BigInteger; 4 | 5 | /** 6 | * Represents an algebraic structure. 7 | * 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | * @since 1.0.0 10 | */ 11 | public interface Field { 12 | 13 | /** 14 | * Returns a new element which lies in this field. 15 | * 16 | * @return a new element which lies in this field. 17 | * @since 1.0.0 18 | */ 19 | E newElement(); 20 | 21 | /** 22 | * Returns a new element whose value is set deterministically from the length bytes stored 23 | * in the source parameter starting from the passed offset. 24 | * 25 | * @param source the buffer data. 26 | * @param offset the starting offset. 27 | * @param length the number of bytes to be used. 28 | * @return this element modified. 29 | * @since 2.0.0 30 | */ 31 | E newElementFromHash(byte[] source, int offset, int length); 32 | 33 | /** 34 | * Returns a new element whose value is set from the buffer source. 35 | * 36 | * @param source the source of bytes. 37 | * @return the number of bytes read. 38 | * @since 2.0.0 39 | */ 40 | E newElementFromBytes(byte[] source); 41 | 42 | /** 43 | * Returns a new element whose value is set from the buffer source starting from offset. 44 | * 45 | * @param source the source of bytes. 46 | * @param offset the starting offset. 47 | * @return the number of bytes read. 48 | * @since 2.0.0 49 | */ 50 | E newElementFromBytes(byte[] source, int offset); 51 | 52 | /** 53 | * Returns a new element whose value is zero. 54 | * 55 | * @return a new element whose value is zero. 56 | * @since 1.0.0 57 | */ 58 | E newZeroElement(); 59 | 60 | /** 61 | * Returns a new element whose value is one. 62 | * 63 | * @return a new element whose value is one. 64 | * @since 1.0.0 65 | */ 66 | E newOneElement(); 67 | 68 | /** 69 | * Returns a new random element. 70 | * 71 | * @return a new random element. 72 | * @since 1.0.0 73 | */ 74 | E newRandomElement(); 75 | 76 | /** 77 | * Returns the order of this field. 78 | * 79 | * @return the order of this field. Returns 0 for infinite order. 80 | * @since 1.0.0 81 | */ 82 | BigInteger getOrder(); 83 | 84 | /** 85 | * Returns a quadratic non-residue in this field. It returns always the same element. 86 | * 87 | * @return a quadratic non-residue in this field. 88 | * @since 1.0.0 89 | */ 90 | E getNqr(); 91 | 92 | /** 93 | * Returns the length in bytes needed to represent an element of this Field. 94 | * 95 | * @return the length in bytes needed to represent an element of this Field. 96 | * @since 1.0.0 97 | */ 98 | int getLengthInBytes(); 99 | 100 | /** 101 | * Returns the length in bytes needed to represent an element of this Field. 102 | * 103 | * @return the length in bytes needed to represent an element of this Field. 104 | * @since 1.0.0 105 | */ 106 | int getLengthInBytes(Element e); 107 | 108 | /** 109 | * Computes the component-wise twice. 110 | * 111 | * @param elements the vector of elements to be twiced. 112 | * @return elements twiced. 113 | * @since 1.1.0 114 | */ 115 | Element[] twice(Element[] elements); 116 | 117 | /** 118 | * Computes the component-wise addition between a and b. 119 | * 120 | * @param a an array of elements of the field 121 | * @param b another array of elements of the field to be added to a 122 | * @return the vector a modified by adding b. 123 | * @since 1.1.0 124 | */ 125 | Element[] add(Element[] a, Element[] b); 126 | 127 | /** 128 | * Reads an ElementPowPreProcessing from the buffer source starting from offset. 129 | * 130 | * @param source the source of bytes. 131 | * @param offset the starting offset. 132 | * @return the ElementPowPreProcessing instance. 133 | * @since 1.2.0 134 | */ 135 | ElementPowPreProcessing getElementPowPreProcessingFromBytes(byte[] source, int offset); 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/FieldOver.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | /** 4 | * This interface represents an algebraic structure defined 5 | * over another. 6 | * 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @see Field 9 | * @since 1.0.0 10 | */ 11 | public interface FieldOver extends Field { 12 | 13 | /** 14 | * Returns the target field. 15 | * 16 | * @return the target field. 17 | * @since 1.0.0 18 | */ 19 | F getTargetField(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/Pairing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | /** 4 | * This interface gives access to the pairing functions. 5 | * Pairings involve three groups of prime order r called G1, G2, and GT. 6 | * The pairing is a bilinear map that takes two elements as input, one from G1 and one from G2, and outputs an element of GT. 7 | * Sometimes G1 and G2 are the same group (i.e. the pairing is symmetric) so their elements can be mixed freely. 8 | * In this case the #isSymmetric() function returns true. 9 | * 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | * @since 1.0.0 12 | */ 13 | public interface Pairing { 14 | 15 | /** 16 | * Returns true if this pairing is symmetric, false otherwise. 17 | * 18 | * @return true if this pairing is symmetric, false otherwise. 19 | * @since 1.0.0 20 | */ 21 | boolean isSymmetric(); 22 | 23 | /** 24 | * Returns the degree of the pairing. 25 | * For bilinear maps, this value is 2. 26 | * For multilinear maps, this value represents 27 | * the degree of linearity supported. 28 | * 29 | * @return the degree of the pairing. 30 | * @since 2.0.0 31 | */ 32 | int getDegree(); 33 | 34 | /** 35 | * Return the G1 group. 36 | * 37 | * @return the G1 group. 38 | * @since 1.0.0 39 | */ 40 | Field getG1(); 41 | 42 | /** 43 | * Return the G2 group. 44 | * 45 | * @return the G2 group. 46 | * @since 1.0.0 47 | */ 48 | Field getG2(); 49 | 50 | /** 51 | * Return the GT group which is the group of rth roots of unity. 52 | * 53 | * @return the GT group. 54 | * @since 1.0.0 55 | */ 56 | Field getGT(); 57 | 58 | /** 59 | * Return the Zr group. 60 | * 61 | * @return the Zr group. 62 | * @since 1.0.0 63 | */ 64 | Field getZr(); 65 | 66 | /** 67 | * Returns the field at level index. 68 | * For bilinear maps, Zr has index 0, G1 has index 1, 69 | * G2 has index 2 and GT has index 3. 70 | * 71 | * @return Returns the field at level index 72 | * @since 2.0.0 73 | */ 74 | Field getFieldAt(int index); 75 | 76 | /** 77 | * Returns the index of the field if it belongs 78 | * to this pairing, otherwise it returns -1. 79 | * 80 | * @param field the field whose index has to be determine. 81 | * @return the index of the field if it belongs 82 | * to this pairing, otherwise it returns Unknown. 83 | * @see #getFieldAt(int) 84 | * @since 2.0.0 85 | */ 86 | int getFieldIndex(Field field); 87 | 88 | /** 89 | * Applies the bilinear map. It returns e(in1, in2). g1 must be in the group G1, g2 must be in the group G2. 90 | * 91 | * @param in1 an element from G1. 92 | * @param in2 an element from G2. 93 | * @return an element from GT whose value is assigned by this map applied to in1 and in2. 94 | * @since 1.0.0 95 | */ 96 | Element pairing(Element in1, Element in2); 97 | 98 | /** 99 | * Returns true if optimized 100 | * product of pairing is supported, 101 | * false otherwise. 102 | *

103 | * If optimized product of pairing is supported then 104 | * invoking the #pairing(Element[], Element[]) method should 105 | * guarantee better performance. 106 | * 107 | * @return true if optimized 108 | * product of pairing is supported, 109 | * false otherwise. 110 | * @see #pairing(Element[], Element[]) 111 | * @since 2.0.0 112 | */ 113 | boolean isProductPairingSupported(); 114 | 115 | /** 116 | * Computes the product of pairings, that is 117 | * 'e'('in1'[0], 'in2'[0]) ... 'e'('in1'[n-1], 'in2'[n-1]). 118 | * 119 | * @param in1 must have at least 'n' elements belonging to the groups G1 120 | * @param in2 must have at least 'n' elements belonging to the groups G2 121 | * @return the product of pairings, that is 'e'('in1'[0], 'in2'[0]) ... 'e'('in1'[n-1], 'in2'[n-1]). 122 | * @since 1.1.0 123 | */ 124 | Element pairing(Element[] in1, Element[] in2); 125 | 126 | /** 127 | * Returns the length in bytes needed to represent a PairingPreProcessing structure. 128 | * 129 | * @return the length in bytes needed to represent a PairingPreProcessing structure. 130 | * @see #getPairingPreProcessingFromBytes(byte[]) 131 | * @see #getPairingPreProcessingFromElement(Element) 132 | * @see PairingPreProcessing 133 | * @since 1.2.0 134 | */ 135 | int getPairingPreProcessingLengthInBytes(); 136 | 137 | /** 138 | * Get ready to perform a pairing whose first input is in1, returns the results of time-saving pre-computation. 139 | * 140 | * @param in1 the first input of a pairing execution, used to pre-compute the pairing. 141 | * @return the results of time-saving pre-computation. 142 | * @since 1.0.0 143 | */ 144 | PairingPreProcessing getPairingPreProcessingFromElement(Element in1); 145 | 146 | /** 147 | * Reads a PairingPreProcessing from the buffer source. 148 | * 149 | * @param source the source of bytes. 150 | * @return the PairingPreProcessing instance. 151 | * @since 1.2.0 152 | */ 153 | PairingPreProcessing getPairingPreProcessingFromBytes(byte[] source); 154 | 155 | /** 156 | * Reads a PairingPreProcessing from the buffer source starting from offset. 157 | * 158 | * @param source the source of bytes. 159 | * @param offset the starting offset. 160 | * @return the PairingPreProcessing instance. 161 | * @since 1.2.0 162 | */ 163 | PairingPreProcessing getPairingPreProcessingFromBytes(byte[] source, int offset); 164 | 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/PairingParametersGenerator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | /** 4 | * This interface lets the user to generate all the necessary parameters 5 | * to initialize a pairing. 6 | * 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public interface PairingParametersGenerator

{ 11 | 12 | /** 13 | * Generates the parameters. 14 | * 15 | * @return a map with all the necessary parameters. 16 | * @since 2.0.0 17 | */ 18 | P generate(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/PairingPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | /** 4 | * This interface is used to compute the pairing function when pre-processed information has 5 | * been compute before on the first input which is so fixed for each instance of this interface. 6 | * 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 1.0.0 9 | */ 10 | public interface PairingPreProcessing { 11 | 12 | /** 13 | * Compute the pairing where the second argument is in2. The pre-processed information 14 | * are used for a fast computation 15 | * 16 | * @param in2 the second pairing function argument. 17 | * @return an element from GT whose value is assigned by this map applied to in1 and in2. 18 | * @since 1.0.0 19 | */ 20 | Element pairing(Element in2); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/Point.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | /** 4 | * This interface represents an element with two coordinates. 5 | * (A point over an elliptic curve). 6 | * 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 1.0.0 9 | */ 10 | public interface Point extends Element, Vector { 11 | 12 | /** 13 | * Returns the x-coordinate. 14 | * 15 | * @return the x-coordinate. 16 | * @since 1.0.0 17 | */ 18 | E getX(); 19 | 20 | /** 21 | * Returns the y-coordinate. 22 | * 23 | * @return the y-coordinate. 24 | * @since 1.0.0 25 | */ 26 | E getY(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/Polynomial.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * This element represents a polynomial through its coefficients. 7 | * 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | * @since 1.0.0 10 | */ 11 | public interface Polynomial extends Element, Vector { 12 | 13 | /** 14 | * Returns the degree of this polynomial. 15 | * 16 | * @return the degree of this polynomial. 17 | * @since 1.0.0 18 | */ 19 | int getDegree(); 20 | 21 | /** 22 | * Returns the list of coefficients representing 23 | * this polynomial. 24 | * 25 | * @return the list of coefficients representing 26 | * this polynomial. 27 | * @since 1.0.0 28 | */ 29 | List getCoefficients(); 30 | 31 | /** 32 | * Returns the coefficient at a specified position. 33 | * 34 | * @param index the position of the requested coefficient. 35 | * @return the coefficient at a specified position. 36 | * @since 1.0.0 37 | */ 38 | E getCoefficient(int index); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/jpbc/Vector.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.jpbc; 2 | 3 | /** 4 | * This element represents a vector through its coordinates. 5 | * 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | * @since 1.2.0 8 | */ 9 | public interface Vector extends Element { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/base/AbstractElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.base; 2 | 3 | import com.sun.istack.internal.NotNull; 4 | import it.unisa.dia.gas.jpbc.Element; 5 | import it.unisa.dia.gas.jpbc.ElementPowPreProcessing; 6 | 7 | import java.math.BigInteger; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author Angelo De Caro (jpbclib@gmail.com) 13 | */ 14 | public abstract class AbstractElement implements Element { 15 | 16 | protected F field; 17 | protected boolean immutable = false; 18 | 19 | 20 | protected AbstractElement(F field) { 21 | this.field = field; 22 | } 23 | 24 | 25 | public F getField() { 26 | return field; 27 | } 28 | 29 | public boolean isImmutable() { 30 | return immutable; 31 | } 32 | 33 | public Element getImmutable() { 34 | throw new IllegalStateException("Not Implemented yet!"); 35 | } 36 | 37 | public int getLengthInBytes() { 38 | return field.getLengthInBytes(); 39 | } 40 | 41 | public int setFromBytes(byte[] source) { 42 | return setFromBytes(source, 0); 43 | } 44 | 45 | public int setFromBytes(byte[] source, int offset) { 46 | throw new IllegalStateException("Not Implemented yet!"); 47 | } 48 | 49 | public Element pow(BigInteger n) { 50 | if (BigInteger.ZERO.equals(n)) { 51 | setToOne(); 52 | return this; 53 | } 54 | 55 | elementPowWind(n); 56 | 57 | return this; 58 | } 59 | 60 | public ElementPowPreProcessing getElementPowPreProcessing() { 61 | return new AbstractElementPowPreProcessing(this); 62 | } 63 | 64 | public Element halve() { 65 | return mul(field.newElement().set(2).invert()); 66 | } 67 | 68 | public Element sub(Element element) { 69 | add(element.duplicate().negate()); 70 | return this; 71 | } 72 | 73 | public Element div(Element element) { 74 | return mul(element.duplicate().invert()); 75 | } 76 | 77 | public Element mul(int z) { 78 | mul(field.newElement().set(z)); 79 | 80 | return this; 81 | } 82 | 83 | public Element sqrt() { 84 | throw new IllegalStateException("Not Implemented yet!"); 85 | } 86 | 87 | public byte[] toBytes() { 88 | throw new IllegalStateException("Not Implemented yet!"); 89 | } 90 | 91 | public Element mulZn(Element z) { 92 | return mul(z.toBigInteger()); 93 | } 94 | 95 | public Element square() { 96 | return mul(this); 97 | } 98 | 99 | public Element twice() { 100 | return add(this); 101 | } 102 | 103 | @Override 104 | public boolean equals(Object obj) { 105 | return obj instanceof Element && isEqual((Element) obj); 106 | } 107 | 108 | 109 | private int optimalPowWindowSize(BigInteger n) { 110 | int expBits; 111 | 112 | expBits = n.bitLength(); 113 | 114 | /* try to minimize 2^k + n/(k+1). */ 115 | if (expBits > 9065) 116 | return 8; 117 | if (expBits > 3529) 118 | return 7; 119 | if (expBits > 1324) 120 | return 6; 121 | if (expBits > 474) 122 | return 5; 123 | if (expBits > 157) 124 | return 4; 125 | if (expBits > 47) 126 | return 3; 127 | return 2; 128 | } 129 | 130 | /** 131 | * Builds k-bit lookup window for base a 132 | * 133 | * @param k 134 | * @return 135 | */ 136 | private @NotNull List buildPowWindow(int k) { 137 | int s; 138 | int lookupSize; 139 | List lookup; 140 | 141 | if (k < 1) { /* no window */ 142 | throw new Error("oops"); 143 | } 144 | 145 | /* build 2^k lookup table. lookup[i] = x^i. */ 146 | /* TODO(-): a more careful word-finding algorithm would allow 147 | * us to avoid calculating even lookup entries > 2 148 | */ 149 | lookupSize = 1 << k; 150 | lookup = new ArrayList<>(lookupSize); 151 | 152 | lookup.add(field.newOneElement()); 153 | for (s = 1; s < lookupSize; s++) { 154 | lookup.add(lookup.get(s - 1).duplicate().mul(this)); 155 | } 156 | 157 | return lookup; 158 | } 159 | 160 | /** 161 | * left-to-right exponentiation with k-bit window. 162 | * NB. must have k >= 1. 163 | * 164 | * @param n 165 | */ 166 | private void elementPowWind(BigInteger n) { 167 | /* early abort if raising to power 0 */ 168 | if (n.signum() == 0) { 169 | setToOne(); 170 | return; 171 | } 172 | 173 | int word = 0; /* the word to look up. 0 lookup = buildPowWindow(k); 177 | Element result = field.newElement().setToOne(); 178 | 179 | for (int inword = 0, s = n.bitLength() - 1; s >= 0; s--) { 180 | result.square(); 181 | int bit = n.testBit(s) ? 1 : 0; 182 | 183 | if (inword == 0 && bit == 0) 184 | continue; /* keep scanning. note continue. */ 185 | 186 | if (inword == 0) { /* was scanning, just found word */ 187 | inword = 1; /* so, start new word */ 188 | word = 1; 189 | wbits = 1; 190 | } else { 191 | word = (word << 1) + bit; 192 | wbits++; /* continue word */ 193 | } 194 | 195 | if (wbits == k || s == 0) { 196 | result.mul(lookup.get(word)); 197 | inword = 0; 198 | } 199 | } 200 | 201 | set(result); 202 | } 203 | 204 | 205 | } 206 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/base/AbstractElementPowPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.base; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.ElementPowPreProcessing; 5 | import it.unisa.dia.gas.jpbc.Field; 6 | import it.unisa.dia.gas.plaf.jpbc.util.io.FieldStreamReader; 7 | 8 | import java.math.BigInteger; 9 | 10 | /** 11 | * @author Angelo De Caro (jpbclib@gmail.com) 12 | */ 13 | public class AbstractElementPowPreProcessing implements ElementPowPreProcessing { 14 | private static final int DEFAULT_K = 5; 15 | 16 | private final Field field; 17 | 18 | private final int k; 19 | private final int bits; 20 | private int numLookups; 21 | private Element[][] table; 22 | 23 | 24 | AbstractElementPowPreProcessing(Element g) { 25 | this.field = g.getField(); 26 | this.bits = field.getOrder().bitLength(); 27 | this.k = AbstractElementPowPreProcessing.DEFAULT_K; 28 | 29 | initTable(g); 30 | } 31 | 32 | AbstractElementPowPreProcessing(Field field, byte[] source, int offset) { 33 | this.field = field; 34 | this.bits = field.getOrder().bitLength(); 35 | this.k = AbstractElementPowPreProcessing.DEFAULT_K; 36 | 37 | initTableFromBytes(source, offset); 38 | } 39 | 40 | public Field getField() { 41 | return field; 42 | } 43 | 44 | public Element pow(BigInteger n) { 45 | return powBaseTable(n); 46 | } 47 | 48 | 49 | private void initTableFromBytes(byte[] source, int offset) { 50 | int lookupSize = 1 << k; 51 | numLookups = bits / k + 1; 52 | table = new Element[numLookups][lookupSize]; 53 | 54 | FieldStreamReader in = new FieldStreamReader(field, source, offset); 55 | 56 | for (int i = 0; i < numLookups; i++) 57 | for (int j = 0; j < lookupSize; j++) 58 | table[i][j] = in.readElement(); 59 | } 60 | 61 | /** 62 | * build k-bit base table for n-bit exponentiation w/ base a 63 | * 64 | * @param g an element 65 | */ 66 | private void initTable(Element g) { 67 | int lookupSize = 1 << k; 68 | 69 | numLookups = bits / k + 1; 70 | table = new Element[numLookups][lookupSize]; 71 | 72 | Element multiplier = g.duplicate(); 73 | 74 | for (int i = 0; i < numLookups; i++) { 75 | table[i][0] = field.newOneElement(); 76 | 77 | for (int j = 1; j < lookupSize; j++) { 78 | table[i][j] = multiplier.duplicate().mul(table[i][j - 1]); 79 | } 80 | multiplier.mul(table[i][lookupSize - 1]); 81 | } 82 | } 83 | 84 | private Element powBaseTable(BigInteger n) { 85 | /* early abort if raising to power 0 */ 86 | if (n.signum() == 0) { 87 | return field.newOneElement(); 88 | } 89 | 90 | if (n.compareTo(field.getOrder()) > 0) 91 | n = n.mod(field.getOrder()); 92 | 93 | Element result = field.newOneElement(); 94 | int numLookups = n.bitLength() / k + 1; 95 | 96 | for (int row = 0; row < numLookups; row++) { 97 | int word = 0; 98 | for (int s = 0; s < k; s++) { 99 | word |= (n.testBit(k * row + s) ? 1 : 0) << s; 100 | } 101 | 102 | if (word > 0) { 103 | result.mul(table[row][word]); 104 | } 105 | } 106 | 107 | return result; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/base/AbstractField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.base; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.ElementPowPreProcessing; 5 | import it.unisa.dia.gas.jpbc.Field; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public abstract class AbstractField implements Field { 11 | 12 | protected boolean orderIsOdd = false; 13 | 14 | 15 | public E newElement(int value) { 16 | E e = newElement(); 17 | e.set(value); 18 | 19 | return e; 20 | } 21 | 22 | public E newElementFromHash(byte[] source, int offset, int length) { 23 | E e = newElement(); 24 | e.setFromHash(source, offset, length); 25 | 26 | return e; 27 | } 28 | 29 | public E newElementFromBytes(byte[] source) { 30 | E e = newElement(); 31 | e.setFromBytes(source); 32 | 33 | return e; 34 | } 35 | 36 | public E newElementFromBytes(byte[] source, int offset) { 37 | E e = newElement(); 38 | e.setFromBytes(source, offset); 39 | 40 | return e; 41 | } 42 | 43 | public E newZeroElement() { 44 | E e = newElement(); 45 | e.setToZero(); 46 | 47 | return e; 48 | } 49 | 50 | public E newOneElement() { 51 | E e = newElement(); 52 | e.setToOne(); 53 | 54 | return e; 55 | } 56 | 57 | public E newRandomElement() { 58 | E e = newElement(); 59 | e.setToRandom(); 60 | 61 | return e; 62 | } 63 | 64 | public boolean isOrderOdd() { 65 | return orderIsOdd; 66 | } 67 | 68 | public int getLengthInBytes(Element e) { 69 | return getLengthInBytes(); 70 | } 71 | 72 | public Element[] twice(Element[] elements) { 73 | for (Element element : elements) { 74 | element.twice(); 75 | } 76 | 77 | return elements; 78 | } 79 | 80 | public Element[] add(Element[] a, Element[] b) { 81 | for (int i = 0; i < a.length; i++) { 82 | a[i].add(b[i]); 83 | } 84 | 85 | return a; 86 | } 87 | 88 | public ElementPowPreProcessing getElementPowPreProcessingFromBytes(byte[] source, int offset) { 89 | return new AbstractElementPowPreProcessing(this, source, offset); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/base/AbstractFieldOver.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.base; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.jpbc.FieldOver; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public abstract class AbstractFieldOver extends AbstractField implements FieldOver { 11 | protected final F targetField; 12 | 13 | protected AbstractFieldOver(F targetField) { 14 | this.targetField = targetField; 15 | } 16 | 17 | 18 | public F getTargetField() { 19 | return targetField; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/base/AbstractPointElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.base; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Point; 5 | import it.unisa.dia.gas.jpbc.Vector; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public abstract class AbstractPointElement extends AbstractElement implements Point, Vector { 11 | 12 | protected E x, y; 13 | 14 | 15 | protected AbstractPointElement(F field) { 16 | super(field); 17 | } 18 | 19 | 20 | public E getX() { 21 | return x; 22 | } 23 | 24 | public E getY() { 25 | return y; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/base/AbstractVectorElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.base; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Vector; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | */ 12 | public abstract class AbstractVectorElement extends AbstractElement implements Vector { 13 | 14 | protected List coeff; 15 | 16 | protected AbstractVectorElement(F field) { 17 | super(field); 18 | 19 | this.coeff = new ArrayList<>(); 20 | } 21 | 22 | 23 | public E getAt(int index) { 24 | return coeff.get(index); 25 | } 26 | 27 | public int getSize() { 28 | return coeff.size(); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/curve/ImmutableCurveElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.curve; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutableCurveElement extends CurveElement { 11 | 12 | ImmutableCurveElement(CurveElement curveElement) { 13 | super(curveElement); 14 | this.x = (E) curveElement.getX().getImmutable(); 15 | this.y = (E) curveElement.getY().getImmutable(); 16 | 17 | this.immutable = true; 18 | } 19 | 20 | public Element getImmutable() { 21 | return this; 22 | } 23 | 24 | @Override 25 | public CurveElement set(Element e) { 26 | throw new IllegalStateException("Invalid call on an immutable element"); 27 | } 28 | 29 | @Override 30 | public CurveElement set(int value) { 31 | throw new IllegalStateException("Invalid call on an immutable element"); 32 | } 33 | 34 | @Override 35 | public CurveElement set(BigInteger value) { 36 | throw new IllegalStateException("Invalid call on an immutable element"); 37 | } 38 | 39 | @Override 40 | public CurveElement twice() { 41 | return (CurveElement) super.duplicate().twice().getImmutable(); 42 | } 43 | 44 | @Override 45 | public CurveElement setToZero() { 46 | throw new IllegalStateException("Invalid call on an immutable element"); 47 | } 48 | 49 | @Override 50 | public CurveElement setToOne() { 51 | throw new IllegalStateException("Invalid call on an immutable element"); 52 | } 53 | 54 | @Override 55 | public CurveElement setToRandom() { 56 | throw new IllegalStateException("Invalid call on an immutable element"); 57 | } 58 | 59 | @Override 60 | public int setFromBytes(byte[] source, int offset) { 61 | throw new IllegalStateException("Invalid call on an immutable element"); 62 | } 63 | 64 | @Override 65 | public CurveElement square() { 66 | return (CurveElement) super.duplicate().square().getImmutable(); 67 | } 68 | 69 | @Override 70 | public CurveElement invert() { 71 | return (CurveElement) super.duplicate().invert().getImmutable(); 72 | } 73 | 74 | @Override 75 | public CurveElement negate() { 76 | return (CurveElement) super.duplicate().negate().getImmutable(); 77 | } 78 | 79 | @Override 80 | public CurveElement add(Element e) { 81 | return (CurveElement) super.duplicate().add(e).getImmutable(); 82 | } 83 | 84 | @Override 85 | public CurveElement mul(Element e) { 86 | return (CurveElement) super.duplicate().mul(e).getImmutable(); 87 | } 88 | 89 | @Override 90 | public CurveElement mul(BigInteger n) { 91 | return (CurveElement) super.duplicate().mul(n).getImmutable(); 92 | } 93 | 94 | @Override 95 | public CurveElement mulZn(Element e) { 96 | return (CurveElement) super.duplicate().mulZn(e).getImmutable(); 97 | } 98 | 99 | @Override 100 | public CurveElement setFromHash(byte[] source, int offset, int length) { 101 | throw new IllegalStateException("Invalid call on an immutable element"); 102 | } 103 | 104 | @Override 105 | public int setFromBytes(byte[] source) { 106 | throw new IllegalStateException("Invalid call on an immutable element"); 107 | } 108 | 109 | @Override 110 | public Element pow(BigInteger n) { 111 | return super.duplicate().pow(n).getImmutable(); 112 | } 113 | 114 | @Override 115 | public Element halve() { 116 | return super.duplicate().halve().getImmutable(); 117 | } 118 | 119 | @Override 120 | public Element sub(Element element) { 121 | return super.duplicate().sub(element).getImmutable(); 122 | } 123 | 124 | @Override 125 | public Element div(Element element) { 126 | return super.duplicate().div(element).getImmutable(); 127 | } 128 | 129 | @Override 130 | public Element mul(int z) { 131 | return super.duplicate().mul(z).getImmutable(); 132 | } 133 | 134 | @Override 135 | public Element sqrt() { 136 | return super.duplicate().sqrt().getImmutable(); 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/gt/GTFiniteElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.gt; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractElement; 5 | import it.unisa.dia.gas.plaf.jpbc.pairing.map.PairingMap; 6 | 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | */ 12 | public class GTFiniteElement extends AbstractElement { 13 | private final PairingMap pairing; 14 | Element value; 15 | 16 | 17 | public GTFiniteElement(PairingMap pairing, GTFiniteField field) { 18 | super(field); 19 | 20 | this.pairing = pairing; 21 | this.value = field.getTargetField().newElement().setToOne(); 22 | } 23 | 24 | public GTFiniteElement(PairingMap pairing, GTFiniteField field, Element value) { 25 | super(field); 26 | 27 | this.pairing = pairing; 28 | this.value = value; 29 | } 30 | 31 | GTFiniteElement(GTFiniteElement element) { 32 | super(element.field); 33 | 34 | this.pairing = element.pairing; 35 | this.value = element.value; 36 | } 37 | 38 | 39 | public GTFiniteElement getImmutable() { 40 | if (isImmutable()) 41 | return this; 42 | 43 | return new ImmutableGTFiniteElement(this); 44 | } 45 | 46 | public GTFiniteElement duplicate() { 47 | return new GTFiniteElement(pairing, (GTFiniteField) field, value.duplicate()); 48 | } 49 | 50 | public GTFiniteElement set(Element value) { 51 | this.value.set(((GTFiniteElement) value).value); 52 | 53 | return this; 54 | } 55 | 56 | public GTFiniteElement set(int value) { 57 | this.value.set(value); 58 | 59 | return this; 60 | } 61 | 62 | public GTFiniteElement set(BigInteger value) { 63 | this.value.set(value); 64 | 65 | return this; 66 | } 67 | 68 | public boolean isZero() { 69 | return isOne(); 70 | } 71 | 72 | public boolean isOne() { 73 | return value.isOne(); 74 | } 75 | 76 | public GTFiniteField getField() { 77 | return (GTFiniteField) field; 78 | } 79 | 80 | public GTFiniteElement setToZero() { 81 | value.setToOne(); 82 | 83 | return this; 84 | } 85 | 86 | public GTFiniteElement setToOne() { 87 | value.setToOne(); 88 | 89 | return this; 90 | } 91 | 92 | public GTFiniteElement setToRandom() { 93 | value.setToRandom(); 94 | pairing.finalPow(value); 95 | 96 | return this; 97 | } 98 | 99 | public GTFiniteElement setFromHash(byte[] source, int offset, int length) { 100 | value.setFromHash(source, offset, length); 101 | pairing.finalPow(value); 102 | 103 | return this; 104 | } 105 | 106 | public int setFromBytes(byte[] source) { 107 | return value.setFromBytes(source); 108 | } 109 | 110 | public int setFromBytes(byte[] source, int offset) { 111 | return value.setFromBytes(source, offset); 112 | } 113 | 114 | public GTFiniteElement invert() { 115 | value.invert(); 116 | 117 | return this; 118 | } 119 | 120 | public GTFiniteElement negate() { 121 | return invert(); 122 | } 123 | 124 | public GTFiniteElement add(Element element) { 125 | return mul(element); 126 | } 127 | 128 | public GTFiniteElement sub(Element element) { 129 | return div(element); 130 | } 131 | 132 | public GTFiniteElement div(Element element) { 133 | value.div(((GTFiniteElement) element).value); 134 | 135 | return this; 136 | } 137 | 138 | public GTFiniteElement mul(Element element) { 139 | value.mul(((GTFiniteElement) element).value); 140 | 141 | return this; 142 | } 143 | 144 | public GTFiniteElement mul(BigInteger n) { 145 | return pow(n); 146 | } 147 | 148 | public boolean isSqr() { 149 | throw new IllegalStateException("Not Implemented yet!"); 150 | } 151 | 152 | public GTFiniteElement pow(BigInteger n) { 153 | this.value.pow(n); 154 | 155 | return this; 156 | } 157 | 158 | @Override 159 | public Element powZn(Element n) { 160 | return null; 161 | } 162 | 163 | public boolean isEqual(Element element) { 164 | return this == element || (element instanceof GTFiniteElement && value.isEqual(((GTFiniteElement) element).value)); 165 | 166 | } 167 | 168 | public BigInteger toBigInteger() { 169 | return value.toBigInteger(); 170 | } 171 | 172 | @Override 173 | public byte[] toBytes() { 174 | return value.toBytes(); 175 | } 176 | 177 | public int sign() { 178 | throw new IllegalStateException("Not implemented yet!!!"); 179 | } 180 | 181 | public String toString() { 182 | return value.toString(); 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/gt/GTFiniteField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.gt; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractFieldOver; 5 | import it.unisa.dia.gas.plaf.jpbc.pairing.map.PairingMap; 6 | 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | */ 12 | public class GTFiniteField extends AbstractFieldOver { 13 | private final PairingMap pairing; 14 | private final BigInteger order; 15 | 16 | 17 | public GTFiniteField(BigInteger order, PairingMap pairing, F targetField) { 18 | super(targetField); 19 | 20 | this.order = order; 21 | this.pairing = pairing; 22 | } 23 | 24 | 25 | public GTFiniteElement newElement() { 26 | return new GTFiniteElement(pairing, this); 27 | } 28 | 29 | public BigInteger getOrder() { 30 | return order; 31 | } 32 | 33 | public GTFiniteElement getNqr() { 34 | throw new IllegalStateException("Not Implemented yet!"); 35 | } 36 | 37 | public int getLengthInBytes() { 38 | return getTargetField().getLengthInBytes(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/gt/ImmutableGTFiniteElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.gt; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutableGTFiniteElement extends GTFiniteElement { 11 | 12 | ImmutableGTFiniteElement(GTFiniteElement gtFiniteElement) { 13 | super(gtFiniteElement); 14 | 15 | this.value = gtFiniteElement.value.getImmutable(); 16 | this.immutable = true; 17 | } 18 | 19 | @Override 20 | public GTFiniteElement getImmutable() { 21 | return this; 22 | } 23 | 24 | @Override 25 | public GTFiniteElement set(Element value) { 26 | throw new IllegalStateException("Invalid call on an immutable element"); 27 | } 28 | 29 | @Override 30 | public GTFiniteElement set(int value) { 31 | throw new IllegalStateException("Invalid call on an immutable element"); 32 | } 33 | 34 | @Override 35 | public GTFiniteElement set(BigInteger value) { 36 | throw new IllegalStateException("Invalid call on an immutable element"); 37 | } 38 | 39 | @Override 40 | public GTFiniteElement twice() { 41 | return (GTFiniteElement) duplicate().twice().getImmutable(); 42 | } 43 | 44 | @Override 45 | public GTFiniteElement mul(int z) { 46 | return (GTFiniteElement) duplicate().mul(z).getImmutable(); 47 | } 48 | 49 | @Override 50 | public GTFiniteElement setToZero() { 51 | throw new IllegalStateException("Invalid call on an immutable element"); 52 | } 53 | 54 | @Override 55 | public GTFiniteElement setToOne() { 56 | throw new IllegalStateException("Invalid call on an immutable element"); 57 | } 58 | 59 | @Override 60 | public GTFiniteElement setToRandom() { 61 | throw new IllegalStateException("Invalid call on an immutable element"); 62 | } 63 | 64 | @Override 65 | public GTFiniteElement setFromHash(byte[] source, int offset, int length) { 66 | throw new IllegalStateException("Invalid call on an immutable element"); 67 | } 68 | 69 | @Override 70 | public int setFromBytes(byte[] source) { 71 | throw new IllegalStateException("Invalid call on an immutable element"); 72 | } 73 | 74 | @Override 75 | public int setFromBytes(byte[] source, int offset) { 76 | throw new IllegalStateException("Invalid call on an immutable element"); 77 | } 78 | 79 | @Override 80 | public GTFiniteElement square() { 81 | return (GTFiniteElement) duplicate().square().getImmutable(); 82 | } 83 | 84 | @Override 85 | public GTFiniteElement invert() { 86 | return duplicate().invert().getImmutable(); 87 | } 88 | 89 | @Override 90 | public GTFiniteElement halve() { 91 | return (GTFiniteElement) duplicate().halve().getImmutable(); 92 | } 93 | 94 | @Override 95 | public GTFiniteElement negate() { 96 | return duplicate().negate().getImmutable(); 97 | } 98 | 99 | @Override 100 | public GTFiniteElement add(Element element) { 101 | return duplicate().add(element).getImmutable(); 102 | } 103 | 104 | @Override 105 | public GTFiniteElement sub(Element element) { 106 | return duplicate().sub(element).getImmutable(); 107 | } 108 | 109 | @Override 110 | public GTFiniteElement div(Element element) { 111 | return duplicate().div(element).getImmutable(); 112 | } 113 | 114 | @Override 115 | public GTFiniteElement mul(Element element) { 116 | return duplicate().mul(element).getImmutable(); 117 | } 118 | 119 | @Override 120 | public GTFiniteElement mul(BigInteger n) { 121 | return duplicate().mul(n).getImmutable(); 122 | } 123 | 124 | @Override 125 | public GTFiniteElement mulZn(Element z) { 126 | return (GTFiniteElement) duplicate().mulZn(z).getImmutable(); 127 | } 128 | 129 | @Override 130 | public GTFiniteElement sqrt() { 131 | return (GTFiniteElement) duplicate().sqrt().getImmutable(); 132 | } 133 | 134 | @Override 135 | public GTFiniteElement pow(BigInteger n) { 136 | return duplicate().pow(n).getImmutable(); 137 | } 138 | 139 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/poly/AbstractPolyElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.poly; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Polynomial; 5 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractElement; 6 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractFieldOver; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author Angelo De Caro (jpbclib@gmail.com) 13 | */ 14 | public abstract class AbstractPolyElement 15 | extends AbstractElement implements Polynomial { 16 | 17 | final List coefficients; 18 | 19 | 20 | AbstractPolyElement(F field) { 21 | super(field); 22 | 23 | this.coefficients = new ArrayList<>(); 24 | } 25 | 26 | 27 | int getSize() { 28 | return coefficients.size(); 29 | } 30 | 31 | public List getCoefficients() { 32 | return coefficients; 33 | } 34 | 35 | public E getCoefficient(int index) { 36 | return coefficients.get(index); 37 | } 38 | 39 | public int getDegree() { 40 | return coefficients.size(); 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/poly/ImmutablePolyModElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.poly; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutablePolyModElement extends PolyModElement { 11 | 12 | ImmutablePolyModElement(PolyModElement element) { 13 | super(element.getField()); 14 | 15 | coefficients.clear(); 16 | for (int i = 0; i < field.n; i++) { 17 | coefficients.add((E) element.getCoefficient(i).getImmutable()); 18 | } 19 | this.immutable = true; 20 | } 21 | 22 | @Override 23 | public Element getImmutable() { 24 | return this; 25 | } 26 | 27 | @Override 28 | public PolyModElement set(Element e) { 29 | throw new IllegalStateException("Invalid call on an immutable element"); 30 | } 31 | 32 | @Override 33 | public PolyModElement set(int value) { 34 | throw new IllegalStateException("Invalid call on an immutable element"); 35 | } 36 | 37 | @Override 38 | public PolyModElement set(BigInteger value) { 39 | throw new IllegalStateException("Invalid call on an immutable element"); 40 | } 41 | 42 | @Override 43 | public PolyModElement setToRandom() { 44 | throw new IllegalStateException("Invalid call on an immutable element"); 45 | } 46 | 47 | @Override 48 | public PolyModElement setFromHash(byte[] source, int offset, int length) { 49 | throw new IllegalStateException("Invalid call on an immutable element"); 50 | } 51 | 52 | @Override 53 | public PolyModElement setToZero() { 54 | throw new IllegalStateException("Invalid call on an immutable element"); 55 | } 56 | 57 | @Override 58 | public PolyModElement setToOne() { 59 | throw new IllegalStateException("Invalid call on an immutable element"); 60 | } 61 | 62 | @Override 63 | public PolyModElement map(Element e) { 64 | throw new IllegalStateException("Invalid call on an immutable element"); 65 | } 66 | 67 | @Override 68 | public PolyModElement twice() { 69 | return (PolyModElement) super.duplicate().twice().getImmutable(); 70 | } 71 | 72 | @Override 73 | public PolyModElement square() { 74 | return (PolyModElement) super.duplicate().square().getImmutable(); 75 | } 76 | 77 | @Override 78 | public PolyModElement invert() { 79 | return (PolyModElement) super.duplicate().invert().getImmutable(); 80 | } 81 | 82 | @Override 83 | public PolyModElement negate() { 84 | return (PolyModElement) super.duplicate().negate().getImmutable(); 85 | } 86 | 87 | @Override 88 | public PolyModElement add(Element e) { 89 | return (PolyModElement) super.duplicate().add(e).getImmutable(); 90 | } 91 | 92 | @Override 93 | public PolyModElement sub(Element e) { 94 | return (PolyModElement) super.duplicate().sub(e).getImmutable(); 95 | } 96 | 97 | @Override 98 | public PolyModElement mul(Element e) { 99 | return (PolyModElement) super.duplicate().mul(e).getImmutable(); 100 | } 101 | 102 | @Override 103 | public PolyModElement mul(int z) { 104 | return (PolyModElement) super.duplicate().mul(z).getImmutable(); 105 | } 106 | 107 | @Override 108 | public PolyModElement mul(BigInteger n) { 109 | return (PolyModElement) super.duplicate().mul(n).getImmutable(); 110 | } 111 | 112 | @Override 113 | public Element pow(BigInteger n) { 114 | return super.duplicate().pow(n).getImmutable(); 115 | } 116 | 117 | @Override 118 | public PolyModElement sqrt() { 119 | return (PolyModElement) super.duplicate().sqrt().getImmutable(); 120 | } 121 | 122 | @Override 123 | public int setFromBytes(byte[] source) { 124 | throw new IllegalStateException("Invalid call on an immutable element"); 125 | } 126 | 127 | @Override 128 | public int setFromBytes(byte[] source, int offset) { 129 | throw new IllegalStateException("Invalid call on an immutable element"); 130 | } 131 | 132 | @Override 133 | public Element halve() { 134 | return super.duplicate().halve().getImmutable(); 135 | } 136 | 137 | @Override 138 | public Element div(Element element) { 139 | return super.duplicate().div(element).getImmutable(); 140 | } 141 | 142 | @Override 143 | public Element mulZn(Element z) { 144 | return super.duplicate().mulZn(z).getImmutable(); 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/poly/PolyField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.poly; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractFieldOver; 5 | 6 | import java.math.BigInteger; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | public class PolyField extends AbstractFieldOver { 12 | 13 | public PolyField(F targetField) { 14 | super(targetField); 15 | } 16 | 17 | 18 | public PolyElement newElement() { 19 | return new PolyElement(this); 20 | } 21 | 22 | public BigInteger getOrder() { 23 | throw new IllegalStateException("Not Implemented yet!"); 24 | } 25 | 26 | public PolyElement getNqr() { 27 | throw new IllegalStateException("Not Implemented yet!"); 28 | } 29 | 30 | public int getLengthInBytes() { 31 | throw new IllegalStateException("Not Implemented yet!"); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/poly/PolyModField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.poly; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractFieldOver; 6 | 7 | import java.math.BigInteger; 8 | import java.util.List; 9 | 10 | /** 11 | * @author Angelo De Caro (jpbclib@gmail.com) 12 | */ 13 | public class PolyModField extends AbstractFieldOver { 14 | final PolyElement irreduciblePoly; 15 | private PolyModElement nqr; 16 | private BigInteger order; 17 | int n; 18 | private int fixedLengthInBytes; 19 | 20 | PolyModElement[] xpwr; 21 | 22 | 23 | public PolyModField(PolyElement irreduciblePoly) { 24 | this(irreduciblePoly, null); 25 | } 26 | 27 | public PolyModField(PolyElement irreduciblePoly, BigInteger nqr) { 28 | super((F) irreduciblePoly.getField().getTargetField()); 29 | 30 | this.irreduciblePoly = irreduciblePoly; 31 | init(nqr); 32 | } 33 | 34 | 35 | private void init(BigInteger nqr) { 36 | this.n = irreduciblePoly.getDegree(); 37 | 38 | this.order = targetField.getOrder().pow(irreduciblePoly.getDegree()); 39 | if (nqr != null) { 40 | this.nqr = newElement(); 41 | this.nqr.getCoefficient(0).set(nqr); 42 | } 43 | 44 | // if (order.compareTo(BigInteger.ZERO) != 0) 45 | computeXPowers(); 46 | 47 | if (targetField.getLengthInBytes() < 0) { 48 | //f->length_in_bytes = fq_length_in_bytes; 49 | fixedLengthInBytes = -1; 50 | } else { 51 | fixedLengthInBytes = targetField.getLengthInBytes() * n; 52 | } 53 | } 54 | 55 | 56 | public PolyModElement newElement() { 57 | return new PolyModElement(this); 58 | } 59 | 60 | public BigInteger getOrder() { 61 | return order; 62 | } 63 | 64 | public PolyModElement getNqr() { 65 | return nqr; 66 | } 67 | 68 | public int getLengthInBytes() { 69 | return fixedLengthInBytes; 70 | } 71 | 72 | public int getN() { 73 | return n; 74 | } 75 | 76 | 77 | /** 78 | * compute x^n,...,x^{2n-2} mod poly 79 | */ 80 | private void computeXPowers() { 81 | xpwr = new PolyModElement[n]; 82 | 83 | for (int i = 0; i < n; i++) { 84 | xpwr[i] = newElement(); 85 | } 86 | 87 | xpwr[0].setFromPolyTruncate(irreduciblePoly).negate(); 88 | PolyModElement p0 = newElement(); 89 | 90 | for (int i = 1; i < n; i++) { 91 | List coeff = xpwr[i - 1].getCoefficients(); 92 | List coeff1 = xpwr[i].getCoefficients(); 93 | 94 | coeff1.get(0).setToZero(); 95 | 96 | for (int j = 1; j < n; j++) { 97 | coeff1.get(j).set(coeff.get(j - 1)); 98 | } 99 | p0.set(xpwr[0]).polymodConstMul(coeff.get(n - 1)); 100 | 101 | xpwr[i].add(p0); 102 | } 103 | 104 | // for (PolyModElement polyModElement : xpwr) { 105 | // System.out.println("xprw = " + polyModElement); 106 | // } 107 | 108 | /* 109 | polymod_field_data_ptr p = field - > data; 110 | element_t p0; 111 | element_ptr pwrn; 112 | element_t * coefficients,*coeff1; 113 | int i, j; 114 | int n = p - > n; 115 | element_t * xpwr; 116 | 117 | xpwr = p - > xpwr; 118 | 119 | element_init(p0, field); 120 | for (i = 0; i < n; i++) { 121 | element_init(xpwr[i], field); 122 | } 123 | pwrn = xpwr[0]; 124 | element_poly_to_polymod_truncate(pwrn, poly); 125 | element_neg(pwrn, pwrn); 126 | 127 | for (i = 1; i < n; i++) { 128 | coefficients = xpwr[i - 1] - > data; 129 | coeff1 = xpwr[i] - > data; 130 | 131 | element_set0(coeff1[0]); 132 | for (j = 1; j < n; j++) { 133 | element_set(coeff1[j], coefficients[j - 1]); 134 | } 135 | polymod_const_mul(p0, coefficients[n - 1], pwrn); 136 | element_add(xpwr[i], xpwr[i], p0); 137 | } 138 | element_clear(p0); 139 | */ 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/poly/PolyUtils.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.poly; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | */ 8 | class PolyUtils { 9 | 10 | 11 | static PolyElement constMul(Element a, PolyElement poly) { 12 | int n = poly.getCoefficients().size(); 13 | 14 | PolyElement res = poly.getField().newElement(); 15 | res.ensureSize(n); 16 | 17 | for (int i = 0; i < n; i++) { 18 | res.getCoefficient(i).set(a).mul(poly.getCoefficient(i)); 19 | } 20 | res.removeLeadingZeroes(); 21 | 22 | return res; 23 | } 24 | 25 | public static void div(Element quot, Element rem, PolyElement a, PolyElement b) { 26 | if (b.isZero()) 27 | throw new IllegalArgumentException("Division by zero!"); 28 | 29 | int n = b.getDegree(); 30 | int m = a.getDegree(); 31 | 32 | if (n > m) { 33 | rem.set(a); 34 | quot.setToZero(); 35 | 36 | return; 37 | } 38 | 39 | int k = m - n; 40 | 41 | PolyElement r = a.duplicate(); 42 | PolyElement q = a.getField().newElement(); 43 | q.ensureSize(k + 1); 44 | 45 | Element temp = a.getField().getTargetField().newElement(); 46 | Element bn = b.getCoefficient(n).duplicate().invert(); 47 | 48 | while (k >= 0) { 49 | Element qk = q.getCoefficient(k); 50 | qk.set(bn).mul(r.getCoefficient(m)); 51 | 52 | for (int i = 0; i <= n; i++) { 53 | temp.set(qk).mul(b.getCoefficient(i)); 54 | r.getCoefficient(i + k).sub(temp); 55 | } 56 | k--; 57 | m--; 58 | } 59 | r.removeLeadingZeroes(); 60 | 61 | quot.set(q); 62 | rem.set(r); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/quadratic/DegreeTwoExtensionQuadraticElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.quadratic; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | */ 8 | public class DegreeTwoExtensionQuadraticElement extends QuadraticElement { 9 | 10 | 11 | DegreeTwoExtensionQuadraticElement(DegreeTwoExtensionQuadraticField field) { 12 | super(field); 13 | 14 | this.x = (E) field.getTargetField().newElement(); 15 | this.y = (E) field.getTargetField().newElement(); 16 | } 17 | 18 | private DegreeTwoExtensionQuadraticElement(DegreeTwoExtensionQuadraticElement element) { 19 | super((QuadraticField) element.field); 20 | 21 | this.x = (E) element.x.duplicate(); 22 | this.y = (E) element.y.duplicate(); 23 | } 24 | 25 | 26 | public DegreeTwoExtensionQuadraticElement duplicate() { 27 | return new DegreeTwoExtensionQuadraticElement(this); 28 | } 29 | 30 | public DegreeTwoExtensionQuadraticElement square() { 31 | Element e0 = x.duplicate(); 32 | Element e1 = x.duplicate(); 33 | 34 | e0.add(y).mul(e1.sub(y)); 35 | e1.set(x).mul(y).twice()/*add(e1)*/; 36 | 37 | x.set(e0); 38 | y.set(e1); 39 | 40 | return this; 41 | } 42 | 43 | public DegreeTwoExtensionQuadraticElement invert() { 44 | Element e0 = x.duplicate(); 45 | Element e1 = y.duplicate(); 46 | 47 | e0.square().add(e1.square()).invert(); 48 | 49 | x.mul(e0); 50 | y.mul(e0.negate()); 51 | 52 | return this; 53 | } 54 | 55 | public DegreeTwoExtensionQuadraticElement mul(Element e) { 56 | DegreeTwoExtensionQuadraticElement element = (DegreeTwoExtensionQuadraticElement) e; 57 | 58 | Element e0 = x.duplicate(); 59 | Element e1 = element.x.duplicate(); 60 | Element e2 = x.getField().newElement(); 61 | 62 | // e2 = (x+y) * (x1+y1) 63 | e2.set(e0.add(y)).mul(e1.add(element.y)); 64 | 65 | // e0 = x*x1 66 | e0.set(x).mul(element.x); 67 | // e1 = y*y1 68 | e1.set(y).mul(element.y); 69 | // e2 = (x+y)*(x1+y1) - x*x1 70 | e2.sub(e0); 71 | 72 | // x = x*x1 - y*y1 73 | x.set(e0).sub(e1); 74 | // y = (x+y)*(x1+y1)- x*x1 - y*y1 75 | y.set(e2).sub(e1); 76 | 77 | return this; 78 | } 79 | 80 | public boolean isSqr() { 81 | /* 82 | //x + yi is a square <=> x^2 + y^2 is (in the base field) 83 | 84 | // Proof: (=>) if x+yi = (a+bi)^2, 85 | // then a^2 - b^2 = x, 2ab = y, 86 | // thus (a^2 + b^2)^2 = (a^2 - b^2)^2 + (2ab)^2 = x^2 + y^2 87 | // (<=) Suppose A^2 = x^2 + y^2 88 | // then if there exist a, b satisfying: 89 | // a^2 = (+-A + x)/2, b^2 = (+-A - x)/2 90 | // then (a + bi)^2 = x + yi. 91 | // We show that exactly one of (A + x)/2, (-A + x)/2 92 | // is a quadratic residue (thus a, b do exist). 93 | // Suppose not. Then the product 94 | // (x^2 - A^2) / 4 is some quadratic residue, a contradiction 95 | // since this would imply x^2 - A^2 = -y^2 is also a quadratic residue, 96 | // but we know -1 is not a quadratic residue. 97 | */ 98 | return x.duplicate().square().add(y.duplicate().square()).isSqr(); 99 | } 100 | 101 | public DegreeTwoExtensionQuadraticElement sqrt() { 102 | //if (a+bi)^2 = x+yi then 103 | //2a^2 = x +- sqrt(x^2 + y^2) 104 | //(take the sign such that a exists) and 2ab = y 105 | //[thus 2b^2 = - (x -+ sqrt(x^2 + y^2))] 106 | Element e0 = x.duplicate().square(); 107 | Element e1 = y.duplicate().square(); 108 | e0.add(e1).sqrt(); 109 | 110 | //e0 = sqrt(x^2 + y^2) 111 | e1.set(x).add(e0); 112 | Element e2 = x.getField().newElement().set(2).invert(); 113 | e1.mul(e2); 114 | 115 | //e1 = (x + sqrt(x^2 + y^2))/2 116 | 117 | if (e1.isSqr()) { 118 | e1.sub(e0); 119 | //e1 should be a square 120 | } 121 | e0.set(e1).sqrt(); 122 | e1.set(e0).add(e0); 123 | e1.invert(); 124 | y.mul(e1); 125 | x.set(e0); 126 | 127 | return this; 128 | } 129 | 130 | public boolean isEqual(Element e) { 131 | if (e == this) 132 | return true; 133 | 134 | DegreeTwoExtensionQuadraticElement element = (DegreeTwoExtensionQuadraticElement) e; 135 | 136 | return x.isEqual(element.x) && y.isEqual(element.y); 137 | } 138 | 139 | public String toString() { 140 | return String.format("{x=%s,y=%s}", x, y); 141 | } 142 | 143 | @Override 144 | public Element getImmutable() { 145 | return new ImmutableDegreeTwoExtensionQuadraticElement(this); 146 | } 147 | 148 | 149 | } 150 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/quadratic/DegreeTwoExtensionQuadraticField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.quadratic; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | */ 8 | public class 9 | DegreeTwoExtensionQuadraticField extends QuadraticField { 10 | 11 | public DegreeTwoExtensionQuadraticField(F targetField) { 12 | super(targetField); 13 | } 14 | 15 | 16 | public DegreeTwoExtensionQuadraticElement newElement() { 17 | return new DegreeTwoExtensionQuadraticElement(this); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/quadratic/ImmutableDegreeTwoExtensionQuadraticElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.quadratic; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutableDegreeTwoExtensionQuadraticElement extends DegreeTwoExtensionQuadraticElement { 11 | 12 | ImmutableDegreeTwoExtensionQuadraticElement(DegreeTwoExtensionQuadraticElement element) { 13 | super((DegreeTwoExtensionQuadraticField) element.getField()); 14 | 15 | this.x = (E) element.getX().getImmutable(); 16 | this.y = (E) element.getY().getImmutable(); 17 | 18 | this.immutable = true; 19 | } 20 | 21 | @Override 22 | public Element getImmutable() { 23 | return this; 24 | } 25 | 26 | @Override 27 | public QuadraticElement set(Element e) { 28 | throw new IllegalStateException("Invalid call on an immutable element"); 29 | } 30 | 31 | @Override 32 | public QuadraticElement set(int value) { 33 | throw new IllegalStateException("Invalid call on an immutable element"); 34 | } 35 | 36 | @Override 37 | public QuadraticElement set(BigInteger value) { 38 | throw new IllegalStateException("Invalid call on an immutable element"); 39 | } 40 | 41 | @Override 42 | public QuadraticElement setToZero() { 43 | throw new IllegalStateException("Invalid call on an immutable element"); 44 | } 45 | 46 | @Override 47 | public QuadraticElement setToOne() { 48 | throw new IllegalStateException("Invalid call on an immutable element"); 49 | } 50 | 51 | @Override 52 | public QuadraticElement setToRandom() { 53 | throw new IllegalStateException("Invalid call on an immutable element"); 54 | } 55 | 56 | @Override 57 | public int setFromBytes(byte[] source, int offset) { 58 | throw new IllegalStateException("Invalid call on an immutable element"); 59 | } 60 | 61 | @Override 62 | public QuadraticElement twice() { 63 | return (QuadraticElement) super.duplicate().twice().getImmutable(); 64 | } 65 | 66 | @Override 67 | public QuadraticElement mul(int z) { 68 | return (QuadraticElement) super.duplicate().mul(z).getImmutable(); 69 | } 70 | 71 | @Override 72 | public DegreeTwoExtensionQuadraticElement square() { 73 | return (DegreeTwoExtensionQuadraticElement) super.duplicate().square().getImmutable(); 74 | } 75 | 76 | @Override 77 | public DegreeTwoExtensionQuadraticElement invert() { 78 | return (DegreeTwoExtensionQuadraticElement) super.duplicate().invert().getImmutable(); 79 | } 80 | 81 | @Override 82 | public QuadraticElement negate() { 83 | return (QuadraticElement) super.duplicate().negate().getImmutable(); 84 | } 85 | 86 | @Override 87 | public QuadraticElement add(Element e) { 88 | return (QuadraticElement) super.duplicate().add(e).getImmutable(); 89 | } 90 | 91 | @Override 92 | public QuadraticElement sub(Element e) { 93 | return (QuadraticElement) super.duplicate().sub(e).getImmutable(); 94 | } 95 | 96 | @Override 97 | public DegreeTwoExtensionQuadraticElement mul(Element e) { 98 | return (DegreeTwoExtensionQuadraticElement) super.duplicate().mul(e).getImmutable(); 99 | } 100 | 101 | @Override 102 | public QuadraticElement mul(BigInteger n) { 103 | return (QuadraticElement) super.duplicate().mul(n).getImmutable(); 104 | } 105 | 106 | @Override 107 | public QuadraticElement mulZn(Element e) { 108 | return (QuadraticElement) super.duplicate().mulZn(e).getImmutable(); 109 | } 110 | 111 | @Override 112 | public DegreeTwoExtensionQuadraticElement sqrt() { 113 | return (DegreeTwoExtensionQuadraticElement) super.duplicate().sqrt().getImmutable(); 114 | } 115 | 116 | @Override 117 | public QuadraticElement setFromHash(byte[] source, int offset, int length) { 118 | return (QuadraticElement) super.duplicate().setFromHash(source, offset, length).getImmutable(); 119 | } 120 | 121 | @Override 122 | public int setFromBytes(byte[] source) { 123 | throw new IllegalStateException("Invalid call on an immutable element"); 124 | } 125 | 126 | @Override 127 | public Element pow(BigInteger n) { 128 | return super.duplicate().pow(n).getImmutable(); 129 | } 130 | 131 | @Override 132 | public Element halve() { 133 | return super.duplicate().halve().getImmutable(); 134 | } 135 | 136 | @Override 137 | public Element div(Element element) { 138 | return super.duplicate().div(element).getImmutable(); 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/quadratic/ImmutableQuadraticElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.quadratic; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutableQuadraticElement extends QuadraticElement { 11 | 12 | ImmutableQuadraticElement(QuadraticElement element) { 13 | super(element.getField()); 14 | 15 | this.x = (E) element.getX().getImmutable(); 16 | this.y = (E) element.getY().getImmutable(); 17 | 18 | this.immutable = true; 19 | } 20 | 21 | @Override 22 | public Element getImmutable() { 23 | return this; 24 | } 25 | 26 | @Override 27 | public QuadraticElement set(Element e) { 28 | throw new IllegalStateException("Invalid call on an immutable element"); 29 | } 30 | 31 | @Override 32 | public QuadraticElement set(int value) { 33 | throw new IllegalStateException("Invalid call on an immutable element"); 34 | } 35 | 36 | @Override 37 | public QuadraticElement set(BigInteger value) { 38 | throw new IllegalStateException("Invalid call on an immutable element"); 39 | } 40 | 41 | @Override 42 | public QuadraticElement setToZero() { 43 | throw new IllegalStateException("Invalid call on an immutable element"); 44 | } 45 | 46 | @Override 47 | public QuadraticElement setToOne() { 48 | throw new IllegalStateException("Invalid call on an immutable element"); 49 | } 50 | 51 | @Override 52 | public QuadraticElement setToRandom() { 53 | throw new IllegalStateException("Invalid call on an immutable element"); 54 | } 55 | 56 | @Override 57 | public int setFromBytes(byte[] source, int offset) { 58 | throw new IllegalStateException("Invalid call on an immutable element"); 59 | } 60 | 61 | @Override 62 | public QuadraticElement twice() { 63 | return (QuadraticElement) super.duplicate().twice().getImmutable(); 64 | } 65 | 66 | @Override 67 | public QuadraticElement mul(int z) { 68 | return (QuadraticElement) super.duplicate().mul(z).getImmutable(); 69 | } 70 | 71 | @Override 72 | public QuadraticElement square() { 73 | return (QuadraticElement) super.duplicate().square().getImmutable(); 74 | } 75 | 76 | @Override 77 | public QuadraticElement invert() { 78 | return (QuadraticElement) super.duplicate().invert().getImmutable(); 79 | } 80 | 81 | @Override 82 | public QuadraticElement negate() { 83 | return (QuadraticElement) super.duplicate().negate().getImmutable(); 84 | } 85 | 86 | @Override 87 | public QuadraticElement add(Element e) { 88 | return (QuadraticElement) super.duplicate().add(e).getImmutable(); 89 | } 90 | 91 | @Override 92 | public QuadraticElement sub(Element e) { 93 | return (QuadraticElement) super.duplicate().sub(e).getImmutable(); 94 | } 95 | 96 | @Override 97 | public QuadraticElement mul(Element e) { 98 | return (QuadraticElement) super.duplicate().mul(e).getImmutable(); 99 | } 100 | 101 | @Override 102 | public QuadraticElement mul(BigInteger n) { 103 | return (QuadraticElement) super.duplicate().mul(n).getImmutable(); 104 | } 105 | 106 | @Override 107 | public QuadraticElement mulZn(Element e) { 108 | return (QuadraticElement) super.duplicate().mulZn(e).getImmutable(); 109 | } 110 | 111 | @Override 112 | public QuadraticElement sqrt() { 113 | return (QuadraticElement) super.duplicate().sqrt().getImmutable(); 114 | } 115 | 116 | @Override 117 | public QuadraticElement setFromHash(byte[] source, int offset, int length) { 118 | throw new IllegalStateException("Invalid call on an immutable element"); 119 | } 120 | 121 | @Override 122 | public int setFromBytes(byte[] source) { 123 | throw new IllegalStateException("Invalid call on an immutable element"); 124 | } 125 | 126 | @Override 127 | public Element pow(BigInteger n) { 128 | return super.duplicate().pow(n).getImmutable(); 129 | } 130 | 131 | @Override 132 | public Element halve() { 133 | return super.duplicate().halve().getImmutable(); 134 | } 135 | 136 | @Override 137 | public Element div(Element element) { 138 | return super.duplicate().div(element).getImmutable(); 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/quadratic/QuadraticField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.quadratic; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractFieldOver; 5 | 6 | import java.math.BigInteger; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | public class QuadraticField extends AbstractFieldOver { 12 | private final BigInteger order; 13 | private final int fixedLengthInBytes; 14 | 15 | 16 | public QuadraticField(F targetField) { 17 | super(targetField); 18 | 19 | this.order = targetField.getOrder().multiply(targetField.getOrder()); 20 | 21 | if (targetField.getLengthInBytes() < 0) { 22 | //f->length_in_bytes = fq_length_in_bytes; 23 | fixedLengthInBytes = -1; 24 | } else { 25 | fixedLengthInBytes = 2 * targetField.getLengthInBytes(); 26 | } 27 | } 28 | 29 | public E newElement() { 30 | return (E) new QuadraticElement(this); 31 | } 32 | 33 | public BigInteger getOrder() { 34 | return order; 35 | } 36 | 37 | public E getNqr() { 38 | throw new IllegalStateException("Not implemented yet!!!"); 39 | } 40 | 41 | public int getLengthInBytes() { 42 | return fixedLengthInBytes; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/vector/ImmutableVectorElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.vector; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutableVectorElement extends VectorElement { 11 | 12 | ImmutableVectorElement(VectorElement element) { 13 | super(element.getField()); 14 | 15 | this.coeff.clear(); 16 | for (int i = 0; i < field.n; i++) 17 | coeff.add((E) element.getAt(i).getImmutable()); 18 | 19 | this.immutable = true; 20 | } 21 | 22 | @Override 23 | public VectorElement getImmutable() { 24 | return this; 25 | } 26 | 27 | @Override 28 | public VectorElement set(Element e) { 29 | throw new IllegalStateException("Invalid call on an immutable element"); 30 | } 31 | 32 | @Override 33 | public VectorElement set(int value) { 34 | throw new IllegalStateException("Invalid call on an immutable element"); 35 | } 36 | 37 | @Override 38 | public VectorElement set(BigInteger value) { 39 | throw new IllegalStateException("Invalid call on an immutable element"); 40 | } 41 | 42 | @Override 43 | public VectorElement twice() { 44 | return duplicate().twice().getImmutable(); 45 | } 46 | 47 | @Override 48 | public VectorElement setToZero() { 49 | throw new IllegalStateException("Invalid call on an immutable element"); 50 | } 51 | 52 | @Override 53 | public VectorElement setToOne() { 54 | throw new IllegalStateException("Invalid call on an immutable element"); 55 | } 56 | 57 | @Override 58 | public VectorElement setToRandom() { 59 | throw new IllegalStateException("Invalid call on an immutable element"); 60 | } 61 | 62 | @Override 63 | public int setFromBytes(byte[] source, int offset) { 64 | throw new IllegalStateException("Invalid call on an immutable element"); 65 | } 66 | 67 | @Override 68 | public VectorElement square() { 69 | return duplicate().square().getImmutable(); 70 | } 71 | 72 | @Override 73 | public VectorElement invert() { 74 | return duplicate().invert().getImmutable(); 75 | } 76 | 77 | @Override 78 | public VectorElement negate() { 79 | return duplicate().negate().getImmutable(); 80 | } 81 | 82 | @Override 83 | public VectorElement add(Element e) { 84 | return duplicate().add(e).getImmutable(); 85 | } 86 | 87 | @Override 88 | public VectorElement mul(Element e) { 89 | return duplicate().mul(e).getImmutable(); 90 | } 91 | 92 | @Override 93 | public VectorElement mul(BigInteger n) { 94 | return duplicate().mul(n).getImmutable(); 95 | } 96 | 97 | @Override 98 | public VectorElement mulZn(Element e) { 99 | return (VectorElement) duplicate().mulZn(e).getImmutable(); 100 | } 101 | 102 | @Override 103 | public VectorElement setFromHash(byte[] source, int offset, int length) { 104 | throw new IllegalStateException("Invalid call on an immutable element"); 105 | } 106 | 107 | @Override 108 | public int setFromBytes(byte[] source) { 109 | throw new IllegalStateException("Invalid call on an immutable element"); 110 | } 111 | 112 | @Override 113 | public Element pow(BigInteger n) { 114 | return duplicate().pow(n).getImmutable(); 115 | } 116 | 117 | @Override 118 | public Element halve() { 119 | return duplicate().halve().getImmutable(); 120 | } 121 | 122 | @Override 123 | public VectorElement sub(Element element) { 124 | return duplicate().sub(element).getImmutable(); 125 | } 126 | 127 | @Override 128 | public Element div(Element element) { 129 | return duplicate().div(element).getImmutable(); 130 | } 131 | 132 | @Override 133 | public VectorElement mul(int z) { 134 | return duplicate().mul(z).getImmutable(); 135 | } 136 | 137 | @Override 138 | public VectorElement sqrt() { 139 | return duplicate().sqrt().getImmutable(); 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/vector/VectorElementPowPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.vector; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.ElementPowPreProcessing; 5 | import it.unisa.dia.gas.jpbc.Field; 6 | 7 | import java.math.BigInteger; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * @author Angelo De Caro (jpbclib@gmail.com) 13 | */ 14 | public class VectorElementPowPreProcessing implements ElementPowPreProcessing { 15 | private final VectorField field; 16 | private final ElementPowPreProcessing[] processing; 17 | 18 | VectorElementPowPreProcessing(VectorElement vector) { 19 | this.field = vector.getField(); 20 | this.processing = new ElementPowPreProcessing[vector.getSize()]; 21 | for (int i = 0; i < processing.length; i++) { 22 | processing[i] = vector.getAt(i).getElementPowPreProcessing(); 23 | } 24 | } 25 | 26 | public Element pow(BigInteger n) { 27 | List coeff = new ArrayList<>(processing.length); 28 | for (ElementPowPreProcessing processing : processing) { 29 | coeff.add(processing.pow(n)); 30 | } 31 | return new VectorElement(field, coeff); 32 | } 33 | 34 | public Field getField() { 35 | return field; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/vector/VectorField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.vector; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractFieldOver; 5 | 6 | import java.math.BigInteger; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | public class VectorField extends AbstractFieldOver { 12 | final int n; 13 | private final int lenInBytes; 14 | 15 | 16 | public VectorField(F targetField, int n) { 17 | super(targetField); 18 | 19 | this.n = n; 20 | this.lenInBytes = n * targetField.getLengthInBytes(); 21 | } 22 | 23 | 24 | public VectorElement newElement() { 25 | return new VectorElement(this); 26 | } 27 | 28 | public BigInteger getOrder() { 29 | throw new IllegalStateException("Not implemented yet!!!"); 30 | } 31 | 32 | public VectorElement getNqr() { 33 | throw new IllegalStateException("Not implemented yet!!!"); 34 | } 35 | 36 | public int getLengthInBytes() { 37 | return lenInBytes; 38 | } 39 | 40 | public int getN() { 41 | return n; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/z/AbstractZElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.z; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractElement; 4 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractField; 5 | 6 | import java.math.BigInteger; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | abstract class AbstractZElement extends AbstractElement { 12 | 13 | BigInteger value; 14 | 15 | AbstractZElement(F field) { 16 | super(field); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/z/ImmutableZrElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.z; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ImmutableZrElement extends ZrElement { 11 | 12 | public ImmutableZrElement(ZrElement zrElement) { 13 | super(zrElement); 14 | this.immutable = true; 15 | } 16 | 17 | @Override 18 | public Element getImmutable() { 19 | return this; 20 | } 21 | 22 | @Override 23 | public ZrElement set(Element value) { 24 | throw new IllegalStateException("Invalid call on an immutable element"); 25 | } 26 | 27 | @Override 28 | public ZrElement set(int value) { 29 | throw new IllegalStateException("Invalid call on an immutable element"); 30 | } 31 | 32 | @Override 33 | public ZrElement set(BigInteger value) { 34 | throw new IllegalStateException("Invalid call on an immutable element"); 35 | } 36 | 37 | @Override 38 | public ZrElement setToZero() { 39 | throw new IllegalStateException("Invalid call on an immutable element"); 40 | } 41 | 42 | @Override 43 | public ZrElement setToOne() { 44 | throw new IllegalStateException("Invalid call on an immutable element"); 45 | } 46 | 47 | @Override 48 | public ZrElement setToRandom() { 49 | throw new IllegalStateException("Invalid call on an immutable element"); 50 | } 51 | 52 | @Override 53 | public ZrElement setFromHash(byte[] source, int offset, int length) { 54 | throw new IllegalStateException("Invalid call on an immutable element"); 55 | } 56 | 57 | @Override 58 | public int setFromBytes(byte[] source) { 59 | throw new IllegalStateException("Invalid call on an immutable element"); 60 | } 61 | 62 | @Override 63 | public int setFromBytes(byte[] source, int offset) { 64 | throw new IllegalStateException("Invalid call on an immutable element"); 65 | } 66 | 67 | @Override 68 | public ZrElement twice() { 69 | return (ZrElement) super.duplicate().twice().getImmutable(); 70 | } 71 | 72 | @Override 73 | public ZrElement mul(int z) { 74 | return (ZrElement) super.duplicate().mul(z).getImmutable(); 75 | } 76 | 77 | @Override 78 | public ZrElement square() { 79 | return (ZrElement) super.duplicate().square().getImmutable(); 80 | } 81 | 82 | @Override 83 | public ZrElement invert() { 84 | return (ZrElement) super.duplicate().invert().getImmutable(); 85 | } 86 | 87 | @Override 88 | public ZrElement halve() { 89 | return (ZrElement) super.duplicate().halve().getImmutable(); 90 | } 91 | 92 | @Override 93 | public ZrElement negate() { 94 | return (ZrElement) super.duplicate().negate().getImmutable(); 95 | } 96 | 97 | @Override 98 | public ZrElement add(Element element) { 99 | return (ZrElement) super.duplicate().add(element).getImmutable(); 100 | } 101 | 102 | @Override 103 | public ZrElement sub(Element element) { 104 | return (ZrElement) super.duplicate().sub(element).getImmutable(); 105 | } 106 | 107 | @Override 108 | public ZrElement div(Element element) { 109 | return (ZrElement) super.duplicate().div(element).getImmutable(); 110 | } 111 | 112 | @Override 113 | public ZrElement mul(Element element) { 114 | return (ZrElement) super.duplicate().mul(element).getImmutable(); 115 | } 116 | 117 | @Override 118 | public ZrElement mul(BigInteger n) { 119 | return (ZrElement) super.duplicate().mul(n).getImmutable(); 120 | } 121 | 122 | @Override 123 | public ZrElement mulZn(Element z) { 124 | return (ZrElement) super.duplicate().mulZn(z).getImmutable(); 125 | } 126 | 127 | @Override 128 | public ZrElement sqrt() { 129 | return (ZrElement) super.duplicate().sqrt().getImmutable(); 130 | } 131 | 132 | @Override 133 | public ZrElement pow(BigInteger n) { 134 | return (ZrElement) super.duplicate().pow(n).getImmutable(); 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/z/SymmetricZrField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.z; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractField; 4 | import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils; 5 | 6 | import java.math.BigInteger; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | public class SymmetricZrField extends AbstractField { 12 | private final BigInteger order; 13 | final BigInteger halfOrder; 14 | 15 | private SymmetricZrElement nqr; 16 | private final int fixedLengthInBytes; 17 | final BigInteger twoInverse; 18 | 19 | 20 | private SymmetricZrField(BigInteger order, BigInteger nqr) { 21 | this.order = order; 22 | this.orderIsOdd = BigIntegerUtils.isOdd(order); 23 | 24 | this.fixedLengthInBytes = (order.bitLength() + 7) / 8; 25 | 26 | this.twoInverse = BigIntegerUtils.TWO.modInverse(order); 27 | 28 | this.halfOrder = order.divide(BigInteger.valueOf(2)); 29 | 30 | if (nqr != null) 31 | this.nqr = newElement().set(nqr); 32 | } 33 | 34 | 35 | public SymmetricZrElement newElement() { 36 | return new SymmetricZrElement(this); 37 | } 38 | 39 | public BigInteger getOrder() { 40 | return order; 41 | } 42 | 43 | public SymmetricZrElement getNqr() { 44 | if (nqr == null) { 45 | nqr = newElement(); 46 | do { 47 | nqr.setToRandom(); 48 | } while (nqr.isSqr()); 49 | } 50 | 51 | return nqr.duplicate(); 52 | } 53 | 54 | public int getLengthInBytes() { 55 | return fixedLengthInBytes; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/z/ZElement.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.z; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.plaf.jpbc.util.Arrays; 5 | 6 | import java.math.BigInteger; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | public class ZElement extends AbstractZElement { 12 | 13 | 14 | ZElement(ZField field) { 15 | super(field); 16 | 17 | this.value = BigInteger.ZERO; 18 | } 19 | 20 | private ZElement(ZElement zrElement) { 21 | super(zrElement.getField()); 22 | 23 | this.value = zrElement.value; 24 | } 25 | 26 | 27 | public ZField getField() { 28 | return field; 29 | } 30 | 31 | @Override 32 | public Element getImmutable() { 33 | throw new IllegalStateException("Not implemented yet!!!"); 34 | } 35 | 36 | public ZElement duplicate() { 37 | return new ZElement(this); 38 | } 39 | 40 | public ZElement set(Element value) { 41 | this.value = ((AbstractZElement) value).value; 42 | 43 | return this; 44 | } 45 | 46 | public ZElement set(int value) { 47 | this.value = BigInteger.valueOf(value); 48 | 49 | return this; 50 | } 51 | 52 | public ZElement set(BigInteger value) { 53 | this.value = value; 54 | 55 | return this; 56 | } 57 | 58 | public boolean isZero() { 59 | return BigInteger.ZERO.equals(value); 60 | } 61 | 62 | public boolean isOne() { 63 | return BigInteger.ONE.equals(value); 64 | } 65 | 66 | public ZElement twice() { 67 | // this.value = value.multiply(BigIntegerUtils.TWO); 68 | this.value = value.add(value); 69 | 70 | return this; 71 | } 72 | 73 | public ZElement mul(int z) { 74 | this.value = this.value.multiply(BigInteger.valueOf(z)); 75 | 76 | return this; 77 | } 78 | 79 | public ZElement setToZero() { 80 | this.value = BigInteger.ZERO; 81 | 82 | return this; 83 | } 84 | 85 | public ZElement setToOne() { 86 | this.value = BigInteger.ONE; 87 | 88 | return this; 89 | } 90 | 91 | public ZElement setToRandom() { 92 | throw new IllegalStateException("Not implemented yet!!!"); 93 | } 94 | 95 | public ZElement setFromHash(byte[] source, int offset, int length) { 96 | throw new IllegalStateException("Not implemented yet!!!"); 97 | } 98 | 99 | public int setFromBytes(byte[] source) { 100 | return setFromBytes(source, 0); 101 | } 102 | 103 | public int setFromBytes(byte[] source, int offset) { 104 | byte[] buffer = Arrays.copyOf(source, offset, field.getLengthInBytes()); 105 | value = new BigInteger(1, buffer); 106 | 107 | return buffer.length; 108 | } 109 | 110 | public ZElement square() { 111 | // value = value.modPow(BigIntegerUtils.TWO, order); 112 | value = value.multiply(value); 113 | 114 | return this; 115 | } 116 | 117 | public ZElement invert() { 118 | throw new IllegalStateException("Not implemented yet!!!"); 119 | } 120 | 121 | public ZElement halve() { 122 | throw new IllegalStateException("Not implemented yet!!!"); 123 | } 124 | 125 | public ZElement negate() { 126 | value = value.multiply(BigInteger.valueOf(-1)); 127 | 128 | return this; 129 | } 130 | 131 | public ZElement add(Element element) { 132 | value = value.add(((AbstractZElement) element).value); 133 | 134 | return this; 135 | } 136 | 137 | public ZElement sub(Element element) { 138 | value = value.subtract(((AbstractZElement) element).value); 139 | 140 | return this; 141 | } 142 | 143 | public ZElement div(Element element) { 144 | throw new IllegalStateException("Not implemented yet!!!"); 145 | } 146 | 147 | public ZElement mul(Element element) { 148 | value = value.multiply(((AbstractZElement) element).value); 149 | 150 | return this; 151 | } 152 | 153 | public ZElement mul(BigInteger n) { 154 | this.value = this.value.multiply(n); 155 | 156 | return this; 157 | } 158 | 159 | public ZElement mulZn(Element z) { 160 | this.value = this.value.multiply(z.toBigInteger()); 161 | 162 | return this; 163 | } 164 | 165 | public boolean isSqr() { 166 | throw new IllegalStateException("Not implemented yet!!!"); 167 | } 168 | 169 | public ZElement sqrt() { 170 | throw new IllegalStateException("Not implemented yet!!!"); 171 | } 172 | 173 | 174 | public ZElement pow(BigInteger n) { 175 | throw new IllegalStateException("Not implemented yet!!!"); 176 | } 177 | 178 | @Override 179 | public Element powZn(Element n) { 180 | return null; 181 | } 182 | 183 | public boolean isEqual(Element e) { 184 | return this == e || (e instanceof ZElement && value.compareTo(((ZElement) e).value) == 0); 185 | 186 | } 187 | 188 | public BigInteger toBigInteger() { 189 | return value; 190 | } 191 | 192 | @Override 193 | public byte[] toBytes() { 194 | throw new IllegalStateException("Not implemented yet!!!"); 195 | } 196 | 197 | public int sign() { 198 | return value.signum(); 199 | } 200 | 201 | public String toString() { 202 | return value.toString(); 203 | } 204 | 205 | } 206 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/z/ZField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.z; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractField; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public class ZField extends AbstractField { 11 | 12 | public ZElement newElement() { 13 | return new ZElement(this); 14 | } 15 | 16 | public BigInteger getOrder() { 17 | return BigInteger.ZERO; 18 | } 19 | 20 | public ZElement getNqr() { 21 | throw new IllegalStateException("Not implemented yet!!!"); 22 | } 23 | 24 | public int getLengthInBytes() { 25 | return -1; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/field/z/ZrField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.field.z; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.field.base.AbstractField; 4 | import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils; 5 | 6 | import java.math.BigInteger; 7 | import java.security.SecureRandom; 8 | 9 | /** 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | */ 12 | public class ZrField extends AbstractField { 13 | private final BigInteger order; 14 | private ZrElement nqr; 15 | private final int fixedLengthInBytes; 16 | final BigInteger twoInverse; 17 | 18 | 19 | public ZrField(BigInteger order) { 20 | this(new SecureRandom(), order, null); 21 | } 22 | 23 | public ZrField(SecureRandom random, BigInteger order) { 24 | this(random, order, null); 25 | } 26 | 27 | public ZrField(BigInteger order, BigInteger nqr) { 28 | this(new SecureRandom(), order, nqr); 29 | } 30 | 31 | private ZrField(SecureRandom random, BigInteger order, BigInteger nqr) { 32 | this.order = order; 33 | this.orderIsOdd = BigIntegerUtils.isOdd(order); 34 | 35 | this.fixedLengthInBytes = (order.bitLength() + 7) / 8; 36 | 37 | this.twoInverse = BigIntegerUtils.TWO.modInverse(order); 38 | 39 | if (nqr != null) 40 | this.nqr = newElement().set(nqr); 41 | } 42 | 43 | 44 | public ZrElement newElement() { 45 | return new ZrElement<>(this); 46 | } 47 | 48 | public BigInteger getOrder() { 49 | return order; 50 | } 51 | 52 | public ZrElement getNqr() { 53 | if (nqr == null) { 54 | nqr = newElement(); 55 | do { 56 | nqr.setToRandom(); 57 | } while (nqr.isSqr()); 58 | } 59 | 60 | return nqr.duplicate(); 61 | } 62 | 63 | public int getLengthInBytes() { 64 | return fixedLengthInBytes; 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/AbstractPairing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing; 2 | 3 | import it.unisa.dia.gas.jpbc.*; 4 | import it.unisa.dia.gas.plaf.jpbc.pairing.map.PairingMap; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | */ 9 | public abstract class AbstractPairing implements Pairing { 10 | 11 | protected Field G1, G2, GT, Zr; 12 | protected PairingMap pairingMap; 13 | 14 | public boolean isSymmetric() { 15 | return true; 16 | } 17 | 18 | public Field getG1() { 19 | return G1; 20 | } 21 | 22 | public Field getG2() { 23 | return G2; 24 | } 25 | 26 | public Field getZr() { 27 | return Zr; 28 | } 29 | 30 | public int getDegree() { 31 | return 2; 32 | } 33 | 34 | public Field getFieldAt(int index) { 35 | switch (index) { 36 | case 0: 37 | return Zr; 38 | case 1: 39 | return G1; 40 | case 2: 41 | return G2; 42 | case 3: 43 | return GT; 44 | default: 45 | throw new IllegalArgumentException("invalid index"); 46 | } 47 | } 48 | 49 | public Field getGT() { 50 | return GT; 51 | } 52 | 53 | public Element pairing(Element in1, Element in2) { 54 | if (!G1.equals(in1.getField())) 55 | throw new IllegalArgumentException("pairing 1st input mismatch"); 56 | if (!G2.equals(in2.getField())) 57 | throw new IllegalArgumentException("pairing 2nd input mismatch"); 58 | 59 | if (in1.isZero() || in2.isZero()) 60 | return GT.newElement().setToZero(); 61 | 62 | return pairingMap.pairing((Point) in1, (Point) in2); 63 | } 64 | 65 | public PairingPreProcessing getPairingPreProcessingFromElement(Element in1) { 66 | if (!G1.equals(in1.getField())) 67 | throw new IllegalArgumentException("pairing 1st input mismatch"); 68 | 69 | return pairingMap.pairing((Point) in1); 70 | } 71 | 72 | public PairingPreProcessing getPairingPreProcessingFromBytes(byte[] source) { 73 | return pairingMap.pairing(source, 0); 74 | } 75 | 76 | public PairingPreProcessing getPairingPreProcessingFromBytes(byte[] source, int offset) { 77 | return pairingMap.pairing(source, offset); 78 | } 79 | 80 | public int getFieldIndex(Field field) { 81 | if (field == Zr) 82 | return 0; 83 | if (field == G1) 84 | return 1; 85 | if (field == G2) 86 | return 2; 87 | if (field == GT) 88 | return 3; 89 | 90 | return -1; 91 | } 92 | 93 | public boolean isProductPairingSupported() { 94 | return pairingMap.isProductPairingSupported(); 95 | } 96 | 97 | public Element pairing(Element[] in1, Element[] in2) { 98 | if (in1.length != in2.length) 99 | throw new IllegalArgumentException("Array lengths mismatch."); 100 | 101 | for (int i = 0; i < in1.length; i++) { 102 | if (!G1.equals(in1[i].getField())) 103 | throw new IllegalArgumentException("pairing 1st input mismatch"); 104 | if (!G2.equals(in2[i].getField())) 105 | throw new IllegalArgumentException("pairing 2nd input mismatch"); 106 | 107 | if (in1[i].isZero() || in2[i].isZero()) 108 | return GT.newElement().setToZero(); 109 | } 110 | 111 | return pairingMap.pairing(in1, in2); 112 | } 113 | 114 | public int getPairingPreProcessingLengthInBytes() { 115 | return pairingMap.getPairingPreProcessingLengthInBytes(); 116 | } 117 | 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/a/TypeACurveGenerator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.a; 2 | 3 | import com.gazman.bls.utils.RandomHolder; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.jpbc.PairingParameters; 6 | import it.unisa.dia.gas.jpbc.PairingParametersGenerator; 7 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 8 | import it.unisa.dia.gas.plaf.jpbc.field.z.ZrField; 9 | import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.PropertiesParameters; 10 | import it.unisa.dia.gas.plaf.jpbc.util.io.Base64; 11 | import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils; 12 | 13 | import java.math.BigInteger; 14 | import java.security.SecureRandom; 15 | 16 | /** 17 | * @author Angelo De Caro (jpbclib@gmail.com) 18 | */ 19 | public class TypeACurveGenerator implements PairingParametersGenerator { 20 | private final int rbits; 21 | private final int qbits; 22 | private final boolean generateCurveFieldGen; 23 | 24 | 25 | private TypeACurveGenerator(int rbits, int qbits) { 26 | this.rbits = rbits; 27 | this.qbits = qbits; 28 | this.generateCurveFieldGen = true; 29 | } 30 | 31 | public PairingParameters generate() { 32 | boolean found = false; 33 | 34 | BigInteger q; 35 | BigInteger r; 36 | BigInteger h = null; 37 | int exp1, exp2; 38 | int sign0, sign1; 39 | 40 | SecureRandom random = RandomHolder.RANDOM; 41 | do { 42 | // r is picked to be a Solinas prime, that is, 43 | // r has the form 2a +- 2b +- 1 for some integers 0 < b < a. 44 | r = BigInteger.ZERO; 45 | 46 | if (random.nextInt(Integer.MAX_VALUE) % 2 != 0) { 47 | exp2 = rbits - 1; 48 | sign1 = 1; 49 | } else { 50 | exp2 = rbits; 51 | sign1 = -1; 52 | } 53 | r = r.setBit(exp2); 54 | 55 | q = BigInteger.ZERO; 56 | exp1 = (random.nextInt(Integer.MAX_VALUE) % (exp2 - 1)) + 1; 57 | q = q.setBit(exp1); 58 | 59 | if (sign1 > 0) { 60 | r = r.add(q); 61 | } else { 62 | r = r.subtract(q); 63 | } 64 | 65 | if (random.nextInt(Integer.MAX_VALUE) % 2 != 0) { 66 | sign0 = 1; 67 | r = r.add(BigInteger.ONE); 68 | } else { 69 | sign0 = -1; 70 | r = r.subtract(BigInteger.ONE); 71 | } 72 | 73 | if (!r.isProbablePrime(10)) 74 | continue; 75 | 76 | for (int i = 0; i < 10; i++) { 77 | q = BigInteger.ZERO; 78 | int bit = qbits - rbits - 4 + 1; 79 | if (bit < 3) 80 | bit = 3; 81 | q = q.setBit(bit); 82 | 83 | // we randomly generate h where where h is a multiple of four and sufficiently large to 84 | // guarantee (hr)^2 is big enough to resist finite field attacks. 85 | // If h is constrained to be a multiple of three as well, then cube roots are extremely easy to 86 | // compute in Fq: for all x \in Fq we see x^(-(q-2)/3) is the cube root of x, 87 | h = BigIntegerUtils.getRandom(q).multiply(BigIntegerUtils.TWELVE); 88 | 89 | // Next it is checked that q = hr ?1 is prime, if it is the case we have finished. 90 | // Also, we choose q = -1 mod 12 so F_q2 can be implemented as F_q[i] (where i = sqrt(-1)). 91 | // Look at the class DegreeTwoExtensionQuadraticField and DegreeTwoExtensionQuadraticElement 92 | q = h.multiply(r).subtract(BigInteger.ONE); 93 | 94 | if (q.isProbablePrime(10)) { 95 | found = true; 96 | break; 97 | } 98 | } 99 | } while (!found); 100 | 101 | PropertiesParameters params = new PropertiesParameters(); 102 | params.put("type", "a"); 103 | params.put("q", q.toString()); 104 | params.put("r", r.toString()); 105 | params.put("h", h.toString()); 106 | params.put("exp1", String.valueOf(exp1)); 107 | params.put("exp2", String.valueOf(exp2)); 108 | params.put("sign0", String.valueOf(sign0)); 109 | params.put("sign1", String.valueOf(sign1)); 110 | 111 | if (generateCurveFieldGen) { 112 | Field Fq = new ZrField(random, q); 113 | CurveField curveField = new CurveField<>(Fq.newOneElement(), Fq.newZeroElement(), r, h); 114 | params.put("genNoCofac", Base64.encodeBytes(curveField.getGenNoCofac().toBytes())); 115 | } 116 | 117 | return params; 118 | } 119 | 120 | public static void main(String[] args) { 121 | if (args.length < 2) 122 | throw new IllegalArgumentException("Too few arguments. Usage "); 123 | 124 | if (args.length > 2) 125 | throw new IllegalArgumentException("Too many arguments. Usage "); 126 | 127 | Integer rBits = Integer.parseInt(args[0]); 128 | Integer qBits = Integer.parseInt(args[1]); 129 | 130 | TypeACurveGenerator generator = new TypeACurveGenerator(rBits, qBits); 131 | PairingParameters curveParams = generator.generate(); 132 | 133 | System.out.println(curveParams.toString(" ")); 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/a/TypeAPairing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.a; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.jpbc.PairingParameters; 5 | import it.unisa.dia.gas.jpbc.Point; 6 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 7 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 8 | import it.unisa.dia.gas.plaf.jpbc.field.quadratic.DegreeTwoExtensionQuadraticField; 9 | import it.unisa.dia.gas.plaf.jpbc.field.z.ZrField; 10 | import it.unisa.dia.gas.plaf.jpbc.pairing.AbstractPairing; 11 | 12 | import java.math.BigInteger; 13 | 14 | /** 15 | * @author Angelo De Caro (jpbclib@gmail.com) 16 | */ 17 | public class TypeAPairing extends AbstractPairing { 18 | private static final String NAF_MILLER_PROJECTTIVE_METHOD = "naf-miller-projective"; 19 | private static final String MILLER_PROJECTTIVE_METHOD = "miller-projective"; 20 | private static final String MILLER_AFFINE_METHOD = "miller-affine"; 21 | 22 | int exp2; 23 | int exp1; 24 | int sign1; 25 | 26 | BigInteger r; 27 | private BigInteger q; 28 | private BigInteger h; 29 | 30 | BigInteger phikOnr; 31 | 32 | private byte[] genNoCofac; 33 | 34 | Field Fq; 35 | Field Fq2; 36 | Field Eq; 37 | 38 | 39 | public TypeAPairing(PairingParameters params) { 40 | initParams(params); 41 | initMap(params); 42 | initFields(); 43 | } 44 | 45 | 46 | private void initParams(PairingParameters curveParams) { 47 | // validate the type 48 | String type = curveParams.getString("type"); 49 | if (type == null || !"a".equalsIgnoreCase(type)) 50 | throw new IllegalArgumentException("Type not valid. Found '" + type + "'. Expected 'a'."); 51 | 52 | // load params 53 | exp2 = curveParams.getInt("exp2"); 54 | exp1 = curveParams.getInt("exp1"); 55 | sign1 = curveParams.getInt("sign1"); 56 | 57 | r = curveParams.getBigInteger("r"); // r = 2^exp2 + sign1 * 2^exp1 + sign0 * 1 58 | q = curveParams.getBigInteger("q"); // we work in E(F_q) (and E(F_q^2)) 59 | h = curveParams.getBigInteger("h"); // r * h = q + 1 60 | 61 | genNoCofac = curveParams.getBytes("genNoCofac", null); 62 | } 63 | 64 | 65 | private void initFields() { 66 | // Init Zr 67 | Zr = initFp(r); 68 | 69 | // Init Fq 70 | Fq = initFp(q); 71 | 72 | // Init Eq 73 | Eq = initEq(); 74 | 75 | // Init Fq2 76 | Fq2 = initFi(); 77 | 78 | // k=2, hence phi_k(q) = q + 1, phikOnr = (q+1)/r 79 | phikOnr = h; 80 | 81 | // Init G1, G2, GT 82 | G1 = Eq; 83 | G2 = G1; 84 | GT = initGT(); 85 | } 86 | 87 | 88 | private Field initFp(BigInteger order) { 89 | return new ZrField(order); 90 | } 91 | 92 | private Field initEq() { 93 | // Remember the curve is: y^2 = x^3 + ax 94 | return new CurveField<>( 95 | Fq.newOneElement(), // a 96 | Fq.newZeroElement(), // b 97 | r, // order 98 | h, // cofactor (r*h)=q+1=#E(F_q) 99 | genNoCofac); 100 | } 101 | 102 | private Field initFi() { 103 | return new DegreeTwoExtensionQuadraticField(Fq); 104 | } 105 | 106 | private Field initGT() { 107 | return new GTFiniteField(r, pairingMap, Fq2); 108 | } 109 | 110 | 111 | private void initMap(PairingParameters curveParams) { 112 | String method = curveParams.getString("method", NAF_MILLER_PROJECTTIVE_METHOD); 113 | 114 | if (NAF_MILLER_PROJECTTIVE_METHOD.endsWith(method)) { 115 | pairingMap = new TypeATateNafProjectiveMillerPairingMap(this); 116 | } else if (MILLER_PROJECTTIVE_METHOD.equals(method)) 117 | pairingMap = new TypeATateProjectiveMillerPairingMap(this); 118 | else if (MILLER_AFFINE_METHOD.equals(method)) 119 | pairingMap = new TypeATateAffineMillerPairingMap(this); 120 | else 121 | throw new IllegalArgumentException("Pairing method not recognized. Method = " + method); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/a1/TypeA1CurveGenerator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.a1; 2 | 3 | import com.gazman.bls.utils.RandomHolder; 4 | import it.unisa.dia.gas.jpbc.PairingParameters; 5 | import it.unisa.dia.gas.jpbc.PairingParametersGenerator; 6 | import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.PropertiesParameters; 7 | import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils; 8 | 9 | import java.math.BigInteger; 10 | import java.security.SecureRandom; 11 | 12 | /** 13 | * @author Angelo De Caro (jpbclib@gmail.com) 14 | */ 15 | public class TypeA1CurveGenerator implements PairingParametersGenerator { 16 | private final int numPrimes; 17 | private final int bits; 18 | 19 | 20 | private TypeA1CurveGenerator() { 21 | this.numPrimes = 3; 22 | this.bits = 512; 23 | } 24 | 25 | public PairingParameters generate() { 26 | BigInteger[] primes = new BigInteger[numPrimes]; 27 | BigInteger order, n, p; 28 | long l; 29 | 30 | SecureRandom random = RandomHolder.RANDOM; 31 | order = BigInteger.ONE; 32 | for (int i = 0; i < numPrimes; i++) { 33 | 34 | boolean isNew = false; 35 | while (!isNew) { 36 | primes[i] = BigInteger.probablePrime(bits, random); 37 | isNew = true; 38 | for (int j = 0; j < i; j++) { 39 | if (primes[i].equals(primes[j])) { 40 | isNew = false; 41 | break; 42 | } 43 | } 44 | } 45 | 46 | order = order.multiply(primes[i]); 47 | } 48 | l = 4; 49 | n = order.multiply(BigIntegerUtils.FOUR); 50 | 51 | p = n.subtract(BigInteger.ONE); 52 | while (!p.isProbablePrime(10)) { 53 | p = p.add(n); 54 | l += 4; 55 | } 56 | 57 | PropertiesParameters params = new PropertiesParameters(); 58 | params.put("type", "a1"); 59 | params.put("p", p.toString()); 60 | params.put("n", order.toString()); 61 | for (int i = 0; i < primes.length; i++) { 62 | params.put("n" + i, primes[i].toString()); 63 | } 64 | params.put("l", String.valueOf(l)); 65 | 66 | 67 | return params; 68 | } 69 | 70 | public static void main(String[] args) { 71 | TypeA1CurveGenerator generator = new TypeA1CurveGenerator(); 72 | PairingParameters curveParams = generator.generate(); 73 | 74 | System.out.println(curveParams.toString(" ")); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/a1/TypeA1Pairing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.a1; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.jpbc.PairingParameters; 5 | import it.unisa.dia.gas.jpbc.Point; 6 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 7 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 8 | import it.unisa.dia.gas.plaf.jpbc.field.quadratic.DegreeTwoExtensionQuadraticField; 9 | import it.unisa.dia.gas.plaf.jpbc.field.z.ZrField; 10 | import it.unisa.dia.gas.plaf.jpbc.pairing.AbstractPairing; 11 | 12 | import java.math.BigInteger; 13 | 14 | /** 15 | * @author Angelo De Caro (jpbclib@gmail.com) 16 | */ 17 | public class TypeA1Pairing extends AbstractPairing { 18 | private static final String NAF_MILLER_PROJECTTIVE_METHOD = "naf-miller-projective"; 19 | private static final String MILLER_AFFINE_METHOD = "miller-affine"; 20 | 21 | 22 | BigInteger r; 23 | private BigInteger p; 24 | private long l; 25 | 26 | BigInteger phikOnr; 27 | 28 | Field Fp; 29 | Field Fq2; 30 | 31 | 32 | public TypeA1Pairing(PairingParameters params) { 33 | initParams(params); 34 | initMap(params); 35 | initFields(); 36 | } 37 | 38 | private void initParams(PairingParameters curveParams) { 39 | // validate the type 40 | String type = curveParams.getString("type"); 41 | if (type == null || !"a1".equalsIgnoreCase(type)) 42 | throw new IllegalArgumentException("Type not valid. Found '" + type + "'. Expected 'a1'."); 43 | 44 | // load params 45 | p = curveParams.getBigInteger("p"); 46 | r = curveParams.getBigInteger("n"); 47 | l = curveParams.getLong("l"); 48 | } 49 | 50 | 51 | private void initFields() { 52 | // Init Zr 53 | Zr = initFp(r); 54 | 55 | // Init Fp 56 | Fp = initFp(p); 57 | 58 | //k=2, hence phi_k(q) = q + 1, phikOnr = (q+1)/r 59 | phikOnr = BigInteger.valueOf(l); 60 | 61 | // Init Eq 62 | Field eq = initEq(); 63 | 64 | // Init Fq2 65 | Fq2 = initFi(); 66 | 67 | // Init G1, G2, GT 68 | G1 = eq; 69 | G2 = G1; 70 | GT = initGT(); 71 | } 72 | 73 | 74 | private Field initFp(BigInteger order) { 75 | return new ZrField(order); 76 | } 77 | 78 | private Field initEq() { 79 | return new CurveField<>(Fp.newOneElement(), Fp.newZeroElement(), r, phikOnr); 80 | } 81 | 82 | private Field initFi() { 83 | return new DegreeTwoExtensionQuadraticField(Fp); 84 | } 85 | 86 | private Field initGT() { 87 | return new GTFiniteField(r, pairingMap, Fq2); 88 | } 89 | 90 | private void initMap(PairingParameters curveParams) { 91 | String method = curveParams.getString("method", NAF_MILLER_PROJECTTIVE_METHOD); 92 | 93 | if (NAF_MILLER_PROJECTTIVE_METHOD.endsWith(method)) { 94 | pairingMap = new TypeA1TateNafProjectiveMillerPairingMap(this); 95 | } else if (MILLER_AFFINE_METHOD.equals(method)) 96 | pairingMap = new TypeA1TateAffineMillerPairingMap(this); 97 | else 98 | throw new IllegalArgumentException("Pairing method not recognized. Method = " + method); 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/a1/TypeA1TateAffineMillerPairingMap.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.a1; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.jpbc.Point; 6 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveElement; 7 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteElement; 8 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 9 | import it.unisa.dia.gas.plaf.jpbc.pairing.map.AbstractMillerPairingMap; 10 | 11 | import java.math.BigInteger; 12 | 13 | /** 14 | * @author Angelo De Caro (jpbclib@gmail.com) 15 | */ 16 | public class TypeA1TateAffineMillerPairingMap extends AbstractMillerPairingMap { 17 | private final TypeA1Pairing pairing; 18 | 19 | 20 | public TypeA1TateAffineMillerPairingMap(TypeA1Pairing pairing) { 21 | super(pairing); 22 | 23 | this.pairing = pairing; 24 | } 25 | 26 | 27 | public Element pairing(Point in1, Point in2) { 28 | Element Px = in1.getX(); 29 | Element Py = in1.getY(); 30 | 31 | Element Qx = in2.getX(); 32 | Element Qy = in2.getY(); 33 | 34 | Point V = (Point) in1.duplicate(); 35 | Element Vx = V.getX(); 36 | Element Vy = V.getY(); 37 | 38 | Element a = pairing.Fp.newElement(); 39 | Element b = pairing.Fp.newElement(); 40 | Element c = pairing.Fp.newElement(); 41 | Element curveA = pairing.Fp.newOneElement(); 42 | Element e0 = pairing.Fp.newElement(); 43 | 44 | Point f0 = pairing.Fq2.newElement(); 45 | Point out = pairing.Fq2.newElement(); 46 | Point f = pairing.Fq2.newOneElement(); 47 | 48 | for (int m = pairing.r.bitLength() - 2; m > 0; m--) { 49 | tangentStep(f0, a, b, c, Vx, Vy, curveA, e0, Qx, Qy, f); 50 | V.twice(); 51 | 52 | if (pairing.r.testBit(m)) { 53 | lineStep(f0, a, b, c, Vx, Vy, Px, Py, e0, Qx, Qy, f); 54 | V.add(in1); 55 | } 56 | 57 | f.square(); 58 | } 59 | tangentStep(f0, a, b, c, Vx, Vy, curveA, e0, Qx, Qy, f); 60 | 61 | // Tate exponentiation. 62 | // Simpler but slower: 63 | // element_pow_mpz(out, f, p->tateExp); 64 | // Use this trick instead: 65 | f0.set(f).invert(); 66 | f.getY().negate(); 67 | f.mul(f0); 68 | out.set(f).pow(pairing.phikOnr); 69 | 70 | /* We could use this instead but p->h is small so this does not help much 71 | a_tateexp(out, f, f0, p->h); 72 | */ 73 | 74 | return new GTFiniteElement(this, (GTFiniteField) pairing.getGT(), out); 75 | } 76 | 77 | public boolean isProductPairingSupported() { 78 | return true; 79 | } 80 | 81 | public Element pairing(Element[] in1, Element[] in2) { 82 | Field refField = in1[0].getField(); 83 | 84 | CurveElement[] Vs = new CurveElement[in1.length]; 85 | 86 | for (int i = 0; i < in1.length; i++) { 87 | Vs[i] = (CurveElement) in1[i].duplicate(); 88 | } 89 | 90 | 91 | Element a = pairing.Fp.newElement(); 92 | Element b = pairing.Fp.newElement(); 93 | Element c = pairing.Fp.newElement(); 94 | Element curveA = pairing.Fp.newOneElement(); 95 | Element e0 = pairing.Fp.newElement(); 96 | 97 | Point f0 = pairing.Fq2.newElement(); 98 | Point out = pairing.Fq2.newElement(); 99 | Point f = pairing.Fq2.newOneElement(); 100 | 101 | for (int m = pairing.r.bitLength() - 2; m > 0; m--) { 102 | tangentStep(f0, a, b, c, Vs, curveA, e0, in2, f); 103 | 104 | refField.twice(Vs); 105 | 106 | if (pairing.r.testBit(m)) { 107 | lineStep(f0, a, b, c, Vs, in1, e0, in2, f); 108 | refField.add(Vs, in1); 109 | } 110 | 111 | f.square(); 112 | } 113 | tangentStep(f0, a, b, c, Vs, curveA, e0, in2, f); 114 | 115 | // Tate exponentiation. 116 | // Simpler but slower: 117 | // element_pow_mpz(out, f, p->tateExp); 118 | // Use this trick instead: 119 | f0.set(f).invert(); 120 | f.getY().negate(); 121 | f.mul(f0); 122 | out.set(f).pow(pairing.phikOnr); 123 | 124 | /* We could use this instead but p->h is small so this does not help much 125 | a_tateexp(out, f, f0, p->h); 126 | */ 127 | 128 | return new GTFiniteElement(this, (GTFiniteField) pairing.getGT(), out); 129 | } 130 | 131 | public void finalPow(Element element) { 132 | Element t0, t1; 133 | t0 = element.getField().newElement(); 134 | t1 = element.getField().newElement(); 135 | 136 | tatePow((Point) t0, (Point) element, (Point) t1, pairing.phikOnr); 137 | 138 | element.set(t0); 139 | } 140 | 141 | 142 | private void tatePow(Point out, Point in, Point temp, BigInteger cofactor) { 143 | Element in1 = in.getY(); 144 | //simpler but slower: 145 | //element_pow_mpz(out, f, tateExp); 146 | 147 | //1. Exponentiate by q-1 148 | //which is equivalent to the following 149 | 150 | temp.set(in).invert(); 151 | in1.negate(); 152 | in.mul(temp); 153 | 154 | /* element_invert(temp, in); 155 | element_neg(in1, in1); 156 | element_mul(in, in, temp); 157 | */ 158 | //2. Exponentiate by (q+1)/r 159 | 160 | //Instead of: 161 | // element_pow_mpz(out, in, cofactor); 162 | //we use Lucas sequences (see "Compressed Pairings", Scott and Barreto) 163 | lucasOdd(out, in, temp, cofactor); 164 | } 165 | 166 | 167 | protected void millerStep(Point out, Element a, Element b, Element c, Element Qx, Element Qy) { 168 | // we will map Q via (x,y) --> (-x, iy) 169 | // hence: 170 | // Re(a Qx + b Qy + c) = -a Q'x + c and 171 | // Im(a Qx + b Qy + c) = b Q'y 172 | 173 | Element rePart = out.getX(); 174 | Element imPart = out.getY(); 175 | 176 | rePart.set(c).sub(imPart.set(a).mul(Qx)); 177 | imPart.set(b).mul(Qy); 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/accumulator/AbstractPairingAccumulator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.accumulator; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Pairing; 5 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.accumultor.AbstractAccumulator; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | * @since 2.0.0 10 | */ 11 | public abstract class AbstractPairingAccumulator extends AbstractAccumulator implements PairingAccumulator { 12 | 13 | private final Pairing pairing; 14 | 15 | 16 | AbstractPairingAccumulator(Pairing pairing) { 17 | this(pairing, pairing.getGT().newOneElement()); 18 | } 19 | 20 | private AbstractPairingAccumulator(Pairing pairing, Element value) { 21 | this.pairing = pairing; 22 | this.result = value; 23 | } 24 | 25 | 26 | public void addPairing(final Element e1, final Element e2) { 27 | super.accumulate(() -> pairing.pairing(e1, e2)); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/accumulator/MultiThreadedMulPairingAccumulator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.accumulator; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Pairing; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public class MultiThreadedMulPairingAccumulator extends AbstractPairingAccumulator { 11 | 12 | 13 | public MultiThreadedMulPairingAccumulator(Pairing pairing) { 14 | super(pairing); 15 | } 16 | 17 | 18 | protected void reduce(Element value) { 19 | this.result.mul(value); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/accumulator/PairingAccumulator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.accumulator; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.accumultor.Accumulator; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public interface PairingAccumulator extends Accumulator { 11 | 12 | void addPairing(Element e1, Element e2); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/accumulator/PairingAccumulatorFactory.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.accumulator; 2 | 3 | import it.unisa.dia.gas.jpbc.Pairing; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | * @since 2.0.0 8 | */ 9 | public class PairingAccumulatorFactory { 10 | 11 | private static final PairingAccumulatorFactory INSTANCE = new PairingAccumulatorFactory(); 12 | 13 | public static PairingAccumulatorFactory getInstance() { 14 | return INSTANCE; 15 | } 16 | 17 | private final boolean multiThreadingEnabled; 18 | 19 | 20 | private PairingAccumulatorFactory() { 21 | this.multiThreadingEnabled = false; // Runtime.getRuntime().availableProcessors() > 1; 22 | } 23 | 24 | 25 | public PairingAccumulator getPairingMultiplier(Pairing pairing) { 26 | return isMultiThreadingEnabled() ? new MultiThreadedMulPairingAccumulator(pairing) 27 | : new SequentialMulPairingAccumulator(pairing); 28 | } 29 | 30 | private boolean isMultiThreadingEnabled() { 31 | return multiThreadingEnabled; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/accumulator/SequentialMulPairingAccumulator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.accumulator; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Pairing; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public class SequentialMulPairingAccumulator implements PairingAccumulator { 11 | 12 | private final Pairing pairing; 13 | private final Element value; 14 | 15 | 16 | public SequentialMulPairingAccumulator(Pairing pairing) { 17 | this.pairing = pairing; 18 | this.value = pairing.getGT().newOneElement(); 19 | } 20 | 21 | public Element getResult() { 22 | return value; 23 | } 24 | 25 | public void addPairing(Element e1, Element e2) { 26 | value.mul(pairing.pairing(e1, e2)); 27 | 28 | } 29 | 30 | public Element awaitResult() { 31 | return value; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/e/TypeECurveGenerator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.e; 2 | 3 | import com.gazman.bls.utils.RandomHolder; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.jpbc.PairingParameters; 6 | import it.unisa.dia.gas.jpbc.PairingParametersGenerator; 7 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 8 | import it.unisa.dia.gas.plaf.jpbc.field.z.ZrField; 9 | import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.PropertiesParameters; 10 | import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils; 11 | 12 | import java.math.BigInteger; 13 | import java.security.SecureRandom; 14 | 15 | /** 16 | * @author Angelo De Caro (jpbclib@gmail.com) 17 | */ 18 | public class TypeECurveGenerator implements PairingParametersGenerator { 19 | private final int rBits; 20 | private final int qBits; 21 | 22 | 23 | private TypeECurveGenerator(int rBits, int qBits) { 24 | this.rBits = rBits; 25 | this.qBits = qBits; 26 | } 27 | 28 | public PairingParameters generate() { 29 | // 3 takes 2 bits to represent 30 | BigInteger q; 31 | BigInteger r; 32 | BigInteger h = null; 33 | BigInteger n = null; 34 | 35 | // won't find any curves is hBits is too low 36 | int hBits = (qBits - 2) / 2 - rBits; 37 | if (hBits < 3) 38 | hBits = 3; 39 | 40 | int exp2; 41 | int exp1; 42 | int sign0, sign1; 43 | 44 | boolean found = false; 45 | SecureRandom random = RandomHolder.RANDOM; 46 | do { 47 | r = BigInteger.ZERO; 48 | 49 | if (random.nextInt(Integer.MAX_VALUE) % 2 != 0) { 50 | exp2 = rBits - 1; 51 | sign1 = 1; 52 | } else { 53 | exp2 = rBits; 54 | sign1 = -1; 55 | } 56 | r = r.setBit(exp2); 57 | 58 | exp1 = (random.nextInt(Integer.MAX_VALUE) % (exp2 - 1)) + 1; 59 | 60 | //use q as a temp variable 61 | q = BigInteger.ZERO.setBit(exp1); 62 | 63 | if (sign1 > 0) { 64 | r = r.add(q); 65 | } else { 66 | r = r.subtract(q); 67 | } 68 | 69 | if (random.nextInt(Integer.MAX_VALUE) % 2 != 0) { 70 | sign0 = 1; 71 | r = r.add(BigInteger.ONE); 72 | } else { 73 | sign0 = -1; 74 | r = r.subtract(BigInteger.ONE); 75 | } 76 | if (!r.isProbablePrime(10)) 77 | continue; 78 | 79 | for (int i = 0; i < 10; i++) { 80 | //use q as a temp variable 81 | q = BigInteger.ZERO.setBit(hBits + 1); 82 | 83 | h = BigIntegerUtils.getRandom(q); 84 | h = h.multiply(h).multiply(BigIntegerUtils.THREE); 85 | 86 | //finally q takes the value it should 87 | n = r.multiply(r).multiply(h); 88 | q = n.add(BigInteger.ONE); 89 | if (q.isProbablePrime(10)) { 90 | found = true; 91 | break; 92 | } 93 | } 94 | } while (!found); 95 | 96 | Field Fq = new ZrField(random, q); 97 | CurveField curveField = new CurveField(Fq.newZeroElement(), Fq.newOneElement(), n); 98 | 99 | // We may need to twist it. 100 | // Pick a random point P and twist the curve if P has the wrong order. 101 | if (!curveField.newRandomElement().mul(n).isZero()) 102 | curveField.twist(); 103 | 104 | PropertiesParameters params = new PropertiesParameters(); 105 | params.put("type", "e"); 106 | params.put("q", q.toString()); 107 | params.put("r", r.toString()); 108 | params.put("h", h.toString()); 109 | params.put("exp1", String.valueOf(exp1)); 110 | params.put("exp2", String.valueOf(exp2)); 111 | params.put("sign0", String.valueOf(sign0)); 112 | params.put("sign1", String.valueOf(sign1)); 113 | params.put("a", curveField.getA().toBigInteger().toString()); 114 | params.put("b", curveField.getB().toBigInteger().toString()); 115 | 116 | return params; 117 | } 118 | 119 | public static void main(String[] args) { 120 | if (args.length < 2) 121 | throw new IllegalArgumentException("Too few arguments. Usage "); 122 | 123 | if (args.length > 2) 124 | throw new IllegalArgumentException("Too many arguments. Usage "); 125 | 126 | Integer rBits = Integer.parseInt(args[0]); 127 | Integer qBits = Integer.parseInt(args[1]); 128 | 129 | PairingParametersGenerator generator = new TypeECurveGenerator(rBits, qBits); 130 | PairingParameters curveParams = generator.generate(); 131 | 132 | System.out.println(curveParams.toString(" ")); 133 | } 134 | 135 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/e/TypeEPairing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.e; 2 | 3 | import it.unisa.dia.gas.jpbc.Field; 4 | import it.unisa.dia.gas.jpbc.PairingParameters; 5 | import it.unisa.dia.gas.jpbc.Point; 6 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 7 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 8 | import it.unisa.dia.gas.plaf.jpbc.field.z.ZrField; 9 | import it.unisa.dia.gas.plaf.jpbc.pairing.AbstractPairing; 10 | 11 | import java.math.BigInteger; 12 | 13 | /** 14 | * @author Angelo De Caro (jpbclib@gmail.com) 15 | */ 16 | public class TypeEPairing extends AbstractPairing { 17 | int exp2; 18 | int exp1; 19 | int sign1; 20 | int sign0; 21 | 22 | private BigInteger r; 23 | private BigInteger q; 24 | private BigInteger h; 25 | private BigInteger a; 26 | private BigInteger b; 27 | 28 | BigInteger phikonr; 29 | Point R; 30 | 31 | Field Fq; 32 | 33 | 34 | public TypeEPairing(PairingParameters properties) { 35 | initParams(properties); 36 | initMap(); 37 | initFields(); 38 | } 39 | 40 | private void initParams(PairingParameters curveParams) { 41 | // validate the type 42 | String type = curveParams.getString("type"); 43 | if (type == null || !"e".equalsIgnoreCase(type)) 44 | throw new IllegalArgumentException("Type not valid. Found '" + type + "'. Expected 'e'."); 45 | 46 | // load params 47 | exp2 = curveParams.getInt("exp2"); 48 | exp1 = curveParams.getInt("exp1"); 49 | sign1 = curveParams.getInt("sign1"); 50 | sign0 = curveParams.getInt("sign0"); 51 | 52 | r = curveParams.getBigInteger("r"); 53 | q = curveParams.getBigInteger("q"); 54 | h = curveParams.getBigInteger("h"); 55 | 56 | a = curveParams.getBigInteger("a"); 57 | b = curveParams.getBigInteger("b"); 58 | } 59 | 60 | 61 | private void initFields() { 62 | // Init Zr 63 | Zr = initFp(r); 64 | 65 | // Init Fq 66 | Fq = initFp(q); 67 | 68 | // Init Eq 69 | CurveField Eq = initEq(); 70 | 71 | // k=1, hence phikOnr = (q-1)/r 72 | phikonr = Fq.getOrder().subtract(BigInteger.ONE).divide(r); 73 | 74 | // Init G1, G2, GT 75 | G1 = Eq; 76 | G2 = G1; 77 | GT = initGT(); 78 | 79 | R = (Point) Eq.getGenNoCofac().duplicate(); 80 | } 81 | 82 | 83 | private Field initFp(BigInteger order) { 84 | return new ZrField(order); 85 | } 86 | 87 | private CurveField initEq() { 88 | return new CurveField<>(Fq.newElement().set(a), Fq.newElement().set(b), 89 | r, h); 90 | } 91 | 92 | private Field initGT() { 93 | return new GTFiniteField(r, pairingMap, Fq); 94 | } 95 | 96 | 97 | private void initMap() { 98 | pairingMap = new TypeETateProjectiveMillerPairingMap(this); 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/f/TypeFTateNoDenomMillerPairingMap.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.f; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Point; 5 | import it.unisa.dia.gas.jpbc.Polynomial; 6 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteElement; 7 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 8 | import it.unisa.dia.gas.plaf.jpbc.pairing.map.AbstractMillerPairingMap; 9 | 10 | public class TypeFTateNoDenomMillerPairingMap extends AbstractMillerPairingMap { 11 | private final TypeFPairing pairingData; 12 | 13 | 14 | public TypeFTateNoDenomMillerPairingMap(TypeFPairing pairing) { 15 | super(pairing); 16 | 17 | this.pairingData = pairing; 18 | } 19 | 20 | 21 | public Element pairing(Point in1, Point in2) { 22 | //map from twist: (x, y) --> (v^-2 x, v^-3 y) 23 | //where v is the sixth root used to construct the twist 24 | //i.e. v^6 = -alpha 25 | //thus v^-2 = -alpha^-1 v^4 26 | //and v^-3 = -alpha^-1 v^3 27 | Point x = (Point) in2.getX().duplicate().mul(pairingData.negAlphaInv); 28 | Point y = (Point) in2.getY().duplicate().mul(pairingData.negAlphaInv); 29 | 30 | return new GTFiniteElement( 31 | this, 32 | (GTFiniteField) pairingData.getGT(), 33 | tateExp((Polynomial) pairing(in1, x, y)) 34 | ); 35 | } 36 | 37 | public void finalPow(Element element) { 38 | element.set(tateExp((Polynomial) element)); 39 | } 40 | 41 | 42 | private Element tateExp(Polynomial element) { 43 | Polynomial x = pairingData.Fq12.newElement(); 44 | Polynomial y = pairingData.Fq12.newElement(); 45 | 46 | qPower(element, y, pairingData.xPowq8); 47 | qPower(element, x, pairingData.xPowq6); 48 | y.mul(x); 49 | qPower(element, x, pairingData.xPowq2); 50 | 51 | return y.mul(x.mul(element).invert()).pow(pairingData.tateExp); 52 | } 53 | 54 | 55 | private void qPower(Polynomial element, Polynomial e1, Element e) { 56 | e1.getCoefficient(0).set(element.getCoefficient(0)); 57 | e1.getCoefficient(1).set(element.getCoefficient(1).duplicate().mul(e)); 58 | 59 | Element epow = e.duplicate().square(); 60 | e1.getCoefficient(2).set(element.getCoefficient(2).duplicate().mul(epow)); 61 | e1.getCoefficient(3).set(element.getCoefficient(3).duplicate().mul(epow.mul(e))); 62 | e1.getCoefficient(4).set(element.getCoefficient(4).duplicate().mul(epow.mul(e))); 63 | e1.getCoefficient(5).set(element.getCoefficient(5).duplicate().mul(epow.mul(e))); 64 | } 65 | 66 | private Element pairing(Point P, Point Qx, Point Qy) { 67 | Element Px = P.getX(); 68 | Element Py = P.getY(); 69 | 70 | Point Z = (Point) P.duplicate(); 71 | Element Zx = Z.getX(); 72 | Element Zy = Z.getY(); 73 | 74 | Element a = Px.getField().newElement(); 75 | Element b = a.duplicate(); 76 | Element c = a.duplicate(); 77 | Element t0 = a.duplicate(); 78 | Element cca = a.duplicate(); 79 | 80 | Polynomial e0 = pairingData.Fq12.newElement(); 81 | Polynomial v = (Polynomial) pairingData.Fq12.newOneElement(); 82 | 83 | for (int m = pairingData.r.bitLength() - 2; m > 0; m--) { 84 | computeTangent(a, b, c, Zx, Zy, cca, t0); 85 | millerStep(e0, v, a, b, c, Qx, Qy); 86 | Z.twice(); 87 | 88 | if (pairingData.r.testBit(m)) { 89 | computeLine(a, b, c, Zx, Zy, Px, Py, t0); 90 | millerStep(e0, v, a, b, c, Qx, Qy); 91 | Z.add(P); 92 | } 93 | 94 | v.square(); 95 | } 96 | computeTangent(a, b, c, Zx, Zy, cca, t0); 97 | millerStep(e0, v, a, b, c, Qx, Qy); 98 | 99 | return v; 100 | } 101 | 102 | protected void millerStep(Point out_Renamed, Element a, Element b, Element c, Element Qx, Element Qy) { 103 | } 104 | 105 | private void millerStep(Polynomial e0, Polynomial v, Element a, Element b, Element c, Element Qx, Element Qy) { 106 | // a, b, c lie in Fq 107 | // Qx, Qy lie in Fq^2 108 | // Qx is coefficient of x^4 109 | // Qy is coefficient of x^3 110 | // 111 | // computes v *= (a Qx x^4 + b Qy x^3 + c) 112 | // 113 | // recall x^6 = -alpha thus 114 | // x^4 (u0 + u1 x^1 + ... + u5 x^5) = 115 | // u0 x^4 + u1 x^5 116 | // - alpha u2 - alpha u3 x - alpha u4 x^2 - alpha u5 x^3 117 | // and 118 | // x^4 (u0 + u1 x^1 + ... + u5 x^5) = 119 | // u0 x^3 + u1 x^4 + u2 x^5 120 | // - alpha u3 - alpha u4 x - alpha u5 x^2 121 | 122 | millerStepTerm(0, 2, 3, 2, e0, v, a, b, c, Qx, Qy); 123 | millerStepTerm(1, 3, 4, 2, e0, v, a, b, c, Qx, Qy); 124 | millerStepTerm(2, 4, 5, 2, e0, v, a, b, c, Qx, Qy); 125 | millerStepTerm(3, 5, 0, 1, e0, v, a, b, c, Qx, Qy); 126 | millerStepTerm(4, 0, 1, 0, e0, v, a, b, c, Qx, Qy); 127 | millerStepTerm(5, 1, 2, 0, e0, v, a, b, c, Qx, Qy); 128 | v.set(e0); 129 | } 130 | 131 | private void millerStepTerm(int i, int j, int k, int flag, 132 | Polynomial e0, Polynomial v, 133 | Element a, Element b, Element c, 134 | Element Qx, Element Qy) { 135 | Point e2 = (Point) e0.getCoefficient(i); 136 | Point e1 = (Point) v.getCoefficient(j).duplicate().mul(Qx); 137 | if (flag == 1) 138 | e1.mul(pairingData.negAlpha); 139 | e1.getX().mul(a); 140 | e1.getY().mul(a); 141 | e2.set(v.getCoefficient(k)).mul(Qy); 142 | e2.getX().mul(b); 143 | e2.getY().mul(b); 144 | e2.add(e1); 145 | if (flag == 2) 146 | e2.mul(pairingData.negAlpha); 147 | e1.set(v.getCoefficient(i)); 148 | e1.getX().mul(c); 149 | e1.getY().mul(c); 150 | e2.add(e1); 151 | } 152 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/g/TypeGPairing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.g; 2 | 3 | import it.unisa.dia.gas.jpbc.*; 4 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 5 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 6 | import it.unisa.dia.gas.plaf.jpbc.field.poly.PolyElement; 7 | import it.unisa.dia.gas.plaf.jpbc.field.poly.PolyField; 8 | import it.unisa.dia.gas.plaf.jpbc.field.poly.PolyModElement; 9 | import it.unisa.dia.gas.plaf.jpbc.field.poly.PolyModField; 10 | import it.unisa.dia.gas.plaf.jpbc.field.quadratic.QuadraticField; 11 | import it.unisa.dia.gas.plaf.jpbc.field.z.ZrField; 12 | import it.unisa.dia.gas.plaf.jpbc.pairing.AbstractPairing; 13 | import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils; 14 | 15 | import java.math.BigInteger; 16 | import java.util.List; 17 | 18 | /** 19 | * @author Angelo De Caro (jpbclib@gmail.com) 20 | */ 21 | public class TypeGPairing extends AbstractPairing { 22 | private final PairingParameters curveParams; 23 | 24 | private BigInteger q; 25 | private BigInteger n; 26 | BigInteger r; 27 | private BigInteger h; 28 | private BigInteger a; 29 | private BigInteger b; 30 | private BigInteger nqr; 31 | 32 | PolyModElement xPowq; 33 | PolyModElement xPowq2; 34 | PolyModElement xPowq3; 35 | PolyModElement xPowq4; 36 | Element nqrInverse; 37 | Element nqrInverseSquare; 38 | BigInteger phikOnr; 39 | 40 | private Field Fq; 41 | Field> Fqk; 42 | PolyModField Fqd; 43 | private CurveField Eq; 44 | 45 | 46 | public TypeGPairing(PairingParameters curveParams) { 47 | this.curveParams = curveParams; 48 | 49 | initParams(); 50 | initMap(); 51 | initFields(); 52 | } 53 | 54 | public boolean isSymmetric() { 55 | return false; 56 | } 57 | 58 | 59 | private void initParams() { 60 | // validate the type 61 | String type = curveParams.getString("type"); 62 | if (type == null || !type.equalsIgnoreCase("g")) 63 | throw new IllegalArgumentException("Type not valid. Found '" + type + "'. Expected 'g'."); 64 | 65 | // load params 66 | q = curveParams.getBigInteger("q"); 67 | n = curveParams.getBigInteger("n"); 68 | h = curveParams.getBigInteger("h"); 69 | r = curveParams.getBigInteger("r"); 70 | a = curveParams.getBigInteger("a"); 71 | b = curveParams.getBigInteger("b"); 72 | // k = curveParams.getBigInteger("k"); 73 | // nk = curveParams.getBigInteger("nk"); 74 | // hk = curveParams.getBigInteger("hk"); 75 | nqr = curveParams.getBigInteger("nqr"); 76 | } 77 | 78 | 79 | private void initFields() { 80 | // Init Zr 81 | Zr = initFp(r); 82 | 83 | // Init Fq 84 | Fq = initFp(q); 85 | 86 | // Init the curve 87 | Eq = initEq(); 88 | 89 | // Init Fqx 90 | Field fqx = initPoly(); 91 | 92 | // Init polymod 93 | // First set the coefficient of x^5 to 1 so we can call element_item() 94 | // for the other coefficients. 95 | PolyElement irreduciblePoly = (PolyElement) fqx.newElement(); 96 | List irreduciblePolyCoeff = irreduciblePoly.getCoefficients(); 97 | for (int i = 0; i < 5; i++) 98 | irreduciblePolyCoeff.add(Fq.newElement().set(curveParams.getBigIntegerAt("coeff", i))); 99 | irreduciblePolyCoeff.add(Fq.newOneElement()); 100 | 101 | // init Fq12 102 | Fqd = initPolyMod(irreduciblePoly); 103 | 104 | Fqk = initQuadratic(); 105 | 106 | CurveField etwist = initEqMap().twist(); 107 | 108 | nqrInverse = Fqd.getNqr().duplicate().invert(); 109 | nqrInverseSquare = nqrInverse.duplicate().square(); 110 | 111 | // ndonr temporarily holds the trace. 112 | BigInteger ndonr = q.subtract(n).add(BigInteger.ONE); 113 | 114 | // Negate because we want the order of the twist. 115 | ndonr = ndonr.negate(); 116 | ndonr = BigIntegerUtils.pbc_mpz_curve_order_extn(q, ndonr, 5); 117 | ndonr = ndonr.divide(r); 118 | etwist.setQuotientCmp(ndonr); 119 | 120 | // Compute phi(k)/r = (q^4 - q^3 + ... + 1)/r. 121 | phikOnr = BigInteger.ONE; 122 | phikOnr = phikOnr.subtract(q); 123 | BigInteger z0 = q.multiply(q); 124 | phikOnr = phikOnr.add(z0); 125 | z0 = z0.multiply(q); 126 | phikOnr = phikOnr.subtract(z0); 127 | z0 = z0.multiply(q); 128 | phikOnr = phikOnr.add(z0); 129 | phikOnr = phikOnr.divide(r); 130 | 131 | // Compute xPowq's 132 | xPowq = Fqd.newElement(); 133 | xPowq.getCoefficient(1).setToOne(); 134 | xPowq.pow(q); 135 | xPowq2 = xPowq.duplicate().square(); 136 | xPowq4 = xPowq2.duplicate().square(); 137 | xPowq3 = xPowq2.duplicate().mul(xPowq); 138 | 139 | // Init G1, G2, GT 140 | G1 = Eq; 141 | G2 = etwist; 142 | GT = initGT(); 143 | } 144 | 145 | private Field initFp(BigInteger order) { 146 | return new ZrField(order); 147 | } 148 | 149 | private CurveField initEq() { 150 | return new CurveField(Fq.newElement().set(a), Fq.newElement().set(b), r, h); 151 | } 152 | 153 | private CurveField initEqMap() { 154 | return new CurveField(Fqd.newElement().map(Eq.getA()), Fqd.newElement().map(Eq.getB()), r); 155 | } 156 | 157 | private PolyField initPoly() { 158 | return new PolyField(Fq); 159 | } 160 | 161 | private PolyModField initPolyMod(PolyElement irred) { 162 | return new PolyModField(irred, nqr); 163 | } 164 | 165 | private QuadraticField initQuadratic() { 166 | return new QuadraticField(Fqd); 167 | } 168 | 169 | private Field initGT() { 170 | return new GTFiniteField(r, pairingMap, Fqk); 171 | } 172 | 173 | private void initMap() { 174 | pairingMap = new TypeGTateAffineNoDenomMillerPairingMap(this); 175 | } 176 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/g/TypeGTateAffineNoDenomMillerPairingMap.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.g; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Point; 5 | import it.unisa.dia.gas.jpbc.Polynomial; 6 | import it.unisa.dia.gas.plaf.jpbc.field.curve.CurveField; 7 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteElement; 8 | import it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteField; 9 | import it.unisa.dia.gas.plaf.jpbc.field.poly.PolyModElement; 10 | import it.unisa.dia.gas.plaf.jpbc.pairing.map.AbstractMillerPairingMap; 11 | 12 | import java.util.List; 13 | 14 | public class TypeGTateAffineNoDenomMillerPairingMap extends AbstractMillerPairingMap { 15 | private final TypeGPairing pairing; 16 | 17 | 18 | public TypeGTateAffineNoDenomMillerPairingMap(TypeGPairing pairing) { 19 | super(pairing); 20 | 21 | this.pairing = pairing; 22 | } 23 | 24 | 25 | public Element pairing(Point in1, Point in2) { 26 | // map from twist: (x, y) --> (v^-1 x, v^-(3/2) y) 27 | // where v is the quadratic non-residue used to construct the twist 28 | Polynomial Qx = (Polynomial) in2.getX().duplicate().mul(pairing.nqrInverse); 29 | // v^-3/2 = v^-2 * v^1/2 30 | Polynomial Qy = (Polynomial) in2.getY().duplicate().mul(pairing.nqrInverseSquare); 31 | 32 | return new GTFiniteElement(this, (GTFiniteField) pairing.getGT(), tatePow(pairing(in1, Qx, Qy))); 33 | } 34 | 35 | public void finalPow(Element element) { 36 | element.set(tatePow(element)); 37 | } 38 | 39 | 40 | private Element tatePow(Element element) { 41 | Point e0, e3; 42 | PolyModElement e2; 43 | 44 | e0 = pairing.Fqk.newElement(); 45 | e2 = pairing.Fqd.newElement(); 46 | e3 = pairing.Fqk.newElement(); 47 | 48 | Polynomial e0re = e0.getX(); 49 | Polynomial e0im = e0.getY(); 50 | 51 | Element e0re0 = e0re.getCoefficient(0); 52 | Element e0im0 = e0im.getCoefficient(0); 53 | 54 | Point in = (Point) element; 55 | List inre = in.getX().getCoefficients(); 56 | List inmi = in.getY().getCoefficients(); 57 | 58 | qPower(1, e2, e0re, e0im, e0re0, e0im0, inre, inmi); 59 | e3.set(e0); 60 | e0re.set(in.getX()); 61 | e0im.set(in.getY()).negate(); 62 | e3.mul(e0); 63 | qPower(-1, e2, e0re, e0im, e0re0, e0im0, inre, inmi); 64 | e0.mul(in); 65 | e0.invert(); 66 | in.set(e3).mul(e0); 67 | e0.set(in); 68 | 69 | return lucasEven(e0, pairing.phikOnr); 70 | } 71 | 72 | private void qPower(int sign, PolyModElement e2, 73 | Element e0re, Element e0im, Element e0re0, Element e0im0, 74 | List inre, List inim) { 75 | e2.set(pairing.xPowq).polymodConstMul(inre.get(1)); 76 | e0re.set(e2); 77 | e2.set(pairing.xPowq2).polymodConstMul(inre.get(2)); 78 | e0re.add(e2); 79 | e2.set(pairing.xPowq3).polymodConstMul(inre.get(3)); 80 | e0re.add(e2); 81 | e2.set(pairing.xPowq4).polymodConstMul(inre.get(4)); 82 | e0re.add(e2); 83 | e0re0.add(inre.get(0)); 84 | 85 | if (sign > 0) { 86 | e2.set(pairing.xPowq).polymodConstMul(inim.get(1)); 87 | e0im.set(e2); 88 | e2.set(pairing.xPowq2).polymodConstMul(inim.get(2)); 89 | e0im.add(e2); 90 | e2.set(pairing.xPowq3).polymodConstMul(inim.get(3)); 91 | e0im.add(e2); 92 | e2.set(pairing.xPowq4).polymodConstMul(inim.get(4)); 93 | e0im.add(e2); 94 | 95 | e0im0.add(inim.get(0)); 96 | } else { 97 | e2.set(pairing.xPowq).polymodConstMul(inim.get(1)); 98 | e0im.set(e2).negate(); 99 | e2.set(pairing.xPowq2).polymodConstMul(inim.get(2)); 100 | e0im.sub(e2); 101 | e2.set(pairing.xPowq3).polymodConstMul(inim.get(3)); 102 | e0im.sub(e2); 103 | e2.set(pairing.xPowq4).polymodConstMul(inim.get(4)); 104 | e0im.sub(e2); 105 | e0im0.sub(inim.get(0)); 106 | } 107 | } 108 | 109 | 110 | private Element pairing(Point P, Polynomial Qx, Polynomial Qy) { 111 | Element Px = P.getX(); 112 | Element Py = P.getY(); 113 | 114 | Point Z = (Point) P.duplicate(); 115 | Element Zx = Z.getX(); 116 | Element Zy = Z.getY(); 117 | 118 | Element a = Px.getField().newElement(); 119 | Element b = a.duplicate(); 120 | Element c = a.duplicate(); 121 | Element cca = ((CurveField) P.getField()).getA(); 122 | Element temp = a.duplicate(); 123 | 124 | Point f0 = pairing.Fqk.newElement(); 125 | Element f = pairing.Fqk.newOneElement(); 126 | 127 | for (int m = pairing.r.bitLength() - 2; m > 0; m--) { 128 | tangentStep(f0, a, b, c, Zx, Zy, cca, temp, Qx, Qy, f); 129 | Z.twice(); 130 | 131 | if (pairing.r.testBit(m)) { 132 | lineStep(f0, a, b, c, Zx, Zy, Px, Py, temp, Qx, Qy, f); 133 | Z.add(P); 134 | } 135 | 136 | f.square(); 137 | } 138 | tangentStep(f0, a, b, c, Zx, Zy, cca, temp, Qx, Qy, f); 139 | 140 | return f; 141 | } 142 | 143 | protected void millerStep(Point out, Element a, Element b, Element c, Polynomial Qx, Polynomial Qy) { 144 | // a, b, c are in Fq 145 | // point Q is (Qx, Qy * sqrt(nqr)) where nqr is used to construct 146 | // the quadratic field extension Fqk of Fqd 147 | 148 | Polynomial rePart = out.getX(); 149 | Polynomial imPart = out.getY(); 150 | 151 | int i; 152 | //int d = rePart.getField().getN(); 153 | int d = rePart.getDegree(); 154 | for (i = 0; i < d; i++) { 155 | rePart.getCoefficient(i).set(Qx.getCoefficient(i)).mul(a); 156 | imPart.getCoefficient(i).set(Qy.getCoefficient(i)).mul(b); 157 | } 158 | 159 | rePart.getCoefficient(0).add(c); 160 | } 161 | 162 | } -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/immutable/ImmutableElementPowPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.immutable; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.ElementPowPreProcessing; 5 | import it.unisa.dia.gas.jpbc.Field; 6 | 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | * @since 2.0.0 12 | */ 13 | public class ImmutableElementPowPreProcessing implements ElementPowPreProcessing { 14 | 15 | private final ElementPowPreProcessing elementPowPreProcessing; 16 | private final Field immutableField; 17 | 18 | ImmutableElementPowPreProcessing(ImmutableField immutableField, ElementPowPreProcessing elementPowPreProcessing) { 19 | this.immutableField = immutableField; 20 | this.elementPowPreProcessing = elementPowPreProcessing; 21 | } 22 | 23 | public Field getField() { 24 | return immutableField; 25 | } 26 | 27 | public Element pow(BigInteger n) { 28 | return elementPowPreProcessing.pow(n).getImmutable(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/immutable/ImmutableField.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.immutable; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.ElementPowPreProcessing; 5 | import it.unisa.dia.gas.jpbc.Field; 6 | import it.unisa.dia.gas.plaf.jpbc.util.ElementUtils; 7 | 8 | import java.math.BigInteger; 9 | 10 | /** 11 | * @author Angelo De Caro (jpbclib@gmail.com) 12 | * @since 2.0.0 13 | */ 14 | public class ImmutableField implements Field { 15 | 16 | final Field field; 17 | 18 | 19 | public ImmutableField(Field field) { 20 | this.field = field; 21 | } 22 | 23 | 24 | public Element newElement() { 25 | return field.newElement().getImmutable(); 26 | } 27 | 28 | public Element newZeroElement() { 29 | return field.newZeroElement().getImmutable(); 30 | } 31 | 32 | public Element newOneElement() { 33 | return field.newOneElement().getImmutable(); 34 | } 35 | 36 | public Element newElementFromHash(byte[] source, int offset, int length) { 37 | return field.newElementFromHash(source, offset, length).getImmutable(); 38 | } 39 | 40 | public Element newElementFromBytes(byte[] source) { 41 | return field.newElementFromBytes(source).getImmutable(); 42 | } 43 | 44 | public Element newElementFromBytes(byte[] source, int offset) { 45 | return field.newElementFromBytes(source, offset).getImmutable(); 46 | } 47 | 48 | public Element newRandomElement() { 49 | return field.newRandomElement().getImmutable(); 50 | } 51 | 52 | public BigInteger getOrder() { 53 | return field.getOrder(); 54 | } 55 | 56 | public Element getNqr() { 57 | return field.getNqr(); 58 | } 59 | 60 | public int getLengthInBytes() { 61 | return field.getLengthInBytes(); 62 | } 63 | 64 | public int getLengthInBytes(Element element) { 65 | return field.getLengthInBytes(element); 66 | } 67 | 68 | public Element[] twice(Element[] elements) { 69 | Element[] temp = ElementUtils.duplicate(elements); 70 | return ElementUtils.cloneImmutable(field.twice(temp)); 71 | } 72 | 73 | public Element[] add(Element[] a, Element[] b) { 74 | Element[] temp = ElementUtils.duplicate(a); 75 | return ElementUtils.cloneImmutable(field.add(temp, b)); 76 | } 77 | 78 | public ElementPowPreProcessing getElementPowPreProcessingFromBytes(byte[] source, int offset) { 79 | return new ImmutableElementPowPreProcessing(this, field.getElementPowPreProcessingFromBytes(source, offset)); 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return "ImmutableField{" + 85 | "field=" + field + 86 | '}'; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/immutable/ImmutablePairingPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.immutable; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.PairingPreProcessing; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public class ImmutablePairingPreProcessing implements PairingPreProcessing { 11 | 12 | private final PairingPreProcessing pairingPreProcessing; 13 | 14 | ImmutablePairingPreProcessing(PairingPreProcessing pairingPreProcessing) { 15 | this.pairingPreProcessing = pairingPreProcessing; 16 | } 17 | 18 | public Element pairing(Element in2) { 19 | return pairingPreProcessing.pairing(in2).getImmutable(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/immutable/ImmutableParing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.immutable; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.jpbc.Pairing; 6 | import it.unisa.dia.gas.jpbc.PairingPreProcessing; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author Angelo De Caro (jpbclib@gmail.com) 13 | * @since 2.0.0 14 | */ 15 | public class ImmutableParing implements Pairing { 16 | 17 | private final Pairing pairing; 18 | private final Map fieldMap; 19 | 20 | 21 | public ImmutableParing(Pairing pairing) { 22 | this.pairing = pairing; 23 | this.fieldMap = new HashMap<>(); 24 | } 25 | 26 | 27 | public boolean isSymmetric() { 28 | return pairing.isSymmetric(); 29 | } 30 | 31 | public int getDegree() { 32 | return pairing.getDegree(); 33 | } 34 | 35 | public Field getG1() { 36 | return getFieldAt(1); 37 | } 38 | 39 | public Field getG2() { 40 | return getFieldAt(2); 41 | } 42 | 43 | public Field getGT() { 44 | return getFieldAt(3); 45 | } 46 | 47 | public Field getZr() { 48 | return getFieldAt(0); 49 | } 50 | 51 | public Field getFieldAt(int index) { 52 | return fieldMap.computeIfAbsent(index, i -> new ImmutableField(pairing.getFieldAt(i))); 53 | } 54 | 55 | public int getFieldIndex(Field field) { 56 | if (field instanceof ImmutableField) 57 | return pairing.getFieldIndex(((ImmutableField) field).field); 58 | 59 | return pairing.getFieldIndex(field); 60 | } 61 | 62 | public Element pairing(Element in1, Element in2) { 63 | return pairing.pairing(in1, in2).getImmutable(); 64 | } 65 | 66 | public boolean isProductPairingSupported() { 67 | return pairing.isProductPairingSupported(); 68 | } 69 | 70 | public Element pairing(Element[] in1, Element[] in2) { 71 | return pairing.pairing(in1, in2).getImmutable(); 72 | } 73 | 74 | public int getPairingPreProcessingLengthInBytes() { 75 | return pairing.getPairingPreProcessingLengthInBytes(); 76 | } 77 | 78 | public PairingPreProcessing getPairingPreProcessingFromElement(Element in1) { 79 | return new ImmutablePairingPreProcessing(pairing.getPairingPreProcessingFromElement(in1)); 80 | } 81 | 82 | public PairingPreProcessing getPairingPreProcessingFromBytes(byte[] source) { 83 | return new ImmutablePairingPreProcessing(pairing.getPairingPreProcessingFromBytes(source)); 84 | } 85 | 86 | public PairingPreProcessing getPairingPreProcessingFromBytes(byte[] source, int offset) { 87 | return new ImmutablePairingPreProcessing(pairing.getPairingPreProcessingFromBytes(source, offset)); 88 | } 89 | 90 | @Override 91 | public String toString() { 92 | return "ImmutableParing{" + 93 | "pairing=" + pairing + 94 | '}'; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/map/AbstractMillerPairingPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.map; 2 | 3 | import it.unisa.dia.gas.jpbc.Pairing; 4 | import it.unisa.dia.gas.jpbc.PairingPreProcessing; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | */ 9 | public abstract class AbstractMillerPairingPreProcessing implements PairingPreProcessing { 10 | 11 | protected final AbstractMillerPairingMap.MillerPreProcessingInfo processingInfo; 12 | 13 | 14 | protected AbstractMillerPairingPreProcessing(int processingInfoSize) { 15 | this.processingInfo = new AbstractMillerPairingMap.MillerPreProcessingInfo(processingInfoSize); 16 | } 17 | 18 | protected AbstractMillerPairingPreProcessing(Pairing pairing, byte[] source, int offset) { 19 | this.processingInfo = new AbstractMillerPairingMap.MillerPreProcessingInfo(pairing, source, offset); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/map/AbstractPairingMap.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.map; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Pairing; 5 | import it.unisa.dia.gas.jpbc.PairingPreProcessing; 6 | import it.unisa.dia.gas.jpbc.Point; 7 | import it.unisa.dia.gas.plaf.jpbc.pairing.accumulator.PairingAccumulator; 8 | import it.unisa.dia.gas.plaf.jpbc.pairing.accumulator.PairingAccumulatorFactory; 9 | 10 | /** 11 | * @author Angelo De Caro (jpbclib@gmail.com) 12 | */ 13 | public abstract class AbstractPairingMap implements PairingMap { 14 | 15 | private final Pairing pairing; 16 | 17 | protected AbstractPairingMap(Pairing pairing) { 18 | this.pairing = pairing; 19 | } 20 | 21 | 22 | public boolean isProductPairingSupported() { 23 | return false; 24 | } 25 | 26 | public Element pairing(Element[] in1, Element[] in2) { 27 | PairingAccumulator combiner = PairingAccumulatorFactory.getInstance().getPairingMultiplier(pairing); 28 | for (int i = 0; i < in1.length; i++) 29 | combiner.addPairing(in1[i], in2[i]); 30 | return combiner.awaitResult(); 31 | } 32 | 33 | public int getPairingPreProcessingLengthInBytes() { 34 | return pairing.getG1().getLengthInBytes(); 35 | } 36 | 37 | public PairingPreProcessing pairing(final Point in1) { 38 | return new DefaultPairingPreProcessing(pairing, in1); 39 | } 40 | 41 | public PairingPreProcessing pairing(byte[] source, int offset) { 42 | return new DefaultPairingPreProcessing(pairing, pairing.getG1(), source, offset); 43 | } 44 | 45 | 46 | protected final void pointToAffine(Element Vx, Element Vy, Element z, Element z2, Element e0) { 47 | // Vx = Vx * z^-2 48 | Vx.mul(e0.set(z.invert()).square()); 49 | // Vy = Vy * z^-3 50 | Vy.mul(e0.mul(z)); 51 | 52 | z.setToOne(); 53 | z2.setToOne(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/map/DefaultPairingPreProcessing.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.map; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | import it.unisa.dia.gas.jpbc.Pairing; 6 | import it.unisa.dia.gas.jpbc.PairingPreProcessing; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | * @since 2.0.0 11 | */ 12 | public class DefaultPairingPreProcessing implements PairingPreProcessing { 13 | 14 | private final Pairing pairing; 15 | private final Element in1; 16 | 17 | public DefaultPairingPreProcessing(Pairing pairing, Element in1) { 18 | this.pairing = pairing; 19 | this.in1 = in1; 20 | } 21 | 22 | public DefaultPairingPreProcessing(Pairing pairing, Field field, byte[] source, int offset) { 23 | this.pairing = pairing; 24 | this.in1 = field.newElementFromBytes(source, offset); 25 | } 26 | 27 | public Element pairing(Element in2) { 28 | return pairing.pairing(in1, in2); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/map/PairingMap.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.map; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.PairingPreProcessing; 5 | import it.unisa.dia.gas.jpbc.Point; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | */ 10 | public interface PairingMap { 11 | 12 | Element pairing(Point in1, Point in2); 13 | 14 | boolean isProductPairingSupported(); 15 | 16 | Element pairing(Element[] in1, Element[] in2); 17 | 18 | 19 | void finalPow(Element element); 20 | 21 | 22 | int getPairingPreProcessingLengthInBytes(); 23 | 24 | PairingPreProcessing pairing(Point in1); 25 | 26 | PairingPreProcessing pairing(byte[] source, int offset); 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/pairing/parameters/MutablePairingParameters.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.pairing.parameters; 2 | 3 | import it.unisa.dia.gas.jpbc.PairingParameters; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | * @since 2.0.0 8 | */ 9 | public interface MutablePairingParameters extends PairingParameters { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/Arrays.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util; 2 | 3 | /** 4 | * @author Angelo De Caro (jpbclib@gmail.com) 5 | */ 6 | public class Arrays { 7 | 8 | public static byte[] copyOf(byte[] original, int offset, int newLength) { 9 | int len = Math.min(original.length - offset, newLength); 10 | byte[] copy = new byte[len]; 11 | System.arraycopy(original, offset, copy, 0, len); 12 | return copy; 13 | } 14 | 15 | public static byte[] copyOfRange(byte[] original, int from, int to) { 16 | int newLength = to - from; 17 | if (newLength < 0) 18 | throw new IllegalArgumentException(from + " > " + to); 19 | byte[] copy = new byte[newLength]; 20 | System.arraycopy(original, from, copy, 0, 21 | Math.min(original.length - from, newLength)); 22 | return copy; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/ElementUtils.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | 6 | import java.util.Arrays; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | */ 11 | public class ElementUtils { 12 | 13 | public static Element[] duplicate(Element[] source) { 14 | Element[] target = new Element[source.length]; 15 | for (int i = 0; i < target.length; i++) 16 | target[i] = source[i].duplicate(); 17 | 18 | return target; 19 | } 20 | 21 | public static Element[] cloneImmutable(Element[] source) { 22 | Element[] target = Arrays.copyOf(source, source.length); 23 | 24 | for (int i = 0; i < target.length; i++) { 25 | Element uElement = target[i]; 26 | if (uElement != null && !uElement.isImmutable()) 27 | target[i] = target[i].getImmutable(); 28 | } 29 | 30 | return target; 31 | } 32 | 33 | 34 | public static Element[][] multiply(Element[][] a, Element[][] b) { 35 | int n = a.length; 36 | Field field = a[0][0].getField(); 37 | 38 | Element[][] res = new Element[n][n]; 39 | 40 | for (int i = 0; i < n; i++) { 41 | for (int j = 0; j < n; j++) { 42 | 43 | res[i][j] = field.newZeroElement(); 44 | for (int k = 0; k < n; k++) 45 | res[i][j].add(a[i][k].duplicate().mul(b[k][j])); 46 | } 47 | } 48 | 49 | return res; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/ExecutorServiceUtils.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public class ExecutorServiceUtils { 11 | 12 | private static final ExecutorService fixedThreadPool; 13 | private static final ExecutorService cachedThreadPool; 14 | 15 | static { 16 | fixedThreadPool = Executors.newFixedThreadPool( 17 | Runtime.getRuntime().availableProcessors() * 4 18 | ); 19 | cachedThreadPool = Executors.newCachedThreadPool(); 20 | } 21 | 22 | 23 | private ExecutorServiceUtils() { 24 | } 25 | 26 | 27 | public static ExecutorService getFixedThreadPool() { 28 | return fixedThreadPool; 29 | } 30 | 31 | public static ExecutorService getCachedThreadPool() { 32 | return cachedThreadPool; 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/Pool.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent; 2 | 3 | /** 4 | * @author Angelo De Caro (jpbclib@gmail.com) 5 | * @since 2.0.0 6 | */ 7 | public interface Pool { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/PoolExecutor.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.CompletionService; 5 | import java.util.concurrent.Executor; 6 | import java.util.concurrent.ExecutorCompletionService; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | * @since 2.0.0 11 | */ 12 | public class PoolExecutor implements Pool { 13 | 14 | protected final CompletionService pool; 15 | protected int counter; 16 | 17 | 18 | protected PoolExecutor(Executor executor) { 19 | this.pool = new ExecutorCompletionService<>(executor); 20 | this.counter = 0; 21 | } 22 | 23 | 24 | protected void submit(Callable callable) { 25 | counter++; 26 | pool.submit(callable); 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/accumultor/AbstractAccumulator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent.accumultor; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.ExecutorServiceUtils; 4 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.PoolExecutor; 5 | 6 | import java.util.concurrent.Callable; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | * @since 2.0.0 11 | */ 12 | public abstract class AbstractAccumulator extends PoolExecutor implements Accumulator { 13 | 14 | 15 | protected T result; 16 | 17 | 18 | protected AbstractAccumulator() { 19 | super(ExecutorServiceUtils.getFixedThreadPool()); 20 | } 21 | 22 | 23 | public void accumulate(Callable callable) { 24 | submit(callable); 25 | 26 | } 27 | 28 | private Accumulator awaitTermination() { 29 | try { 30 | for (int i = 0; i < counter; i++) 31 | reduce(pool.take().get()); 32 | } catch (Exception e) { 33 | throw new RuntimeException(e); 34 | } finally { 35 | counter = 0; 36 | } 37 | return this; 38 | } 39 | 40 | public T getResult() { 41 | return result; 42 | } 43 | 44 | public T awaitResult() { 45 | return awaitTermination().getResult(); 46 | } 47 | 48 | 49 | protected abstract void reduce(T value); 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/accumultor/Accumulator.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent.accumultor; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.Pool; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | * @since 2.0.0 8 | */ 9 | public interface Accumulator extends Pool { 10 | 11 | T awaitResult(); 12 | 13 | T getResult(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/context/ContextExecutor.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent.context; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.MutablePairingParameters; 4 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.ExecutorServiceUtils; 5 | import it.unisa.dia.gas.plaf.jpbc.util.concurrent.PoolExecutor; 6 | 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * @author Angelo De Caro (jpbclib@gmail.com) 11 | * @since 2.0.0 12 | */ 13 | public class ContextExecutor extends PoolExecutor implements MutablePairingParameters { 14 | 15 | private final MutablePairingParameters parameters; 16 | 17 | 18 | public ContextExecutor(MutablePairingParameters parameters) { 19 | super(ExecutorServiceUtils.getCachedThreadPool()); 20 | this.parameters = parameters; 21 | } 22 | 23 | public boolean containsKey(String key) { 24 | return parameters.containsKey(key); 25 | } 26 | 27 | public String getString(String key) { 28 | return parameters.getString(key); 29 | } 30 | 31 | public String getString(String key, String defaultValue) { 32 | return parameters.getString(key, defaultValue); 33 | } 34 | 35 | public int getInt(String key) { 36 | return parameters.getInt(key); 37 | } 38 | 39 | public int getInt(String key, int defaultValue) { 40 | return parameters.getInt(key, defaultValue); 41 | } 42 | 43 | public BigInteger getBigInteger(String key) { 44 | return parameters.getBigInteger(key); 45 | } 46 | 47 | public BigInteger getBigIntegerAt(String key, int index) { 48 | return parameters.getBigIntegerAt(key, index); 49 | } 50 | 51 | public BigInteger getBigInteger(String key, BigInteger defaultValue) { 52 | return parameters.getBigInteger(key, defaultValue); 53 | } 54 | 55 | public long getLong(String key) { 56 | return parameters.getLong(key); 57 | } 58 | 59 | public long getLong(String key, long defaultValue) { 60 | return parameters.getLong(key, defaultValue); 61 | } 62 | 63 | public byte[] getBytes(String key) { 64 | return parameters.getBytes(key); 65 | } 66 | 67 | public byte[] getBytes(String key, byte[] defaultValue) { 68 | return parameters.getBytes(key, defaultValue); 69 | } 70 | 71 | public String toString(String separator) { 72 | return parameters.toString(separator); 73 | } 74 | 75 | public Object getObject(String key) { 76 | return parameters.getObject(key); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/context/ContextRunnable.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent.context; 2 | 3 | import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.MutablePairingParameters; 4 | 5 | import java.math.BigInteger; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | * @since 2.0.0 10 | */ 11 | public abstract class ContextRunnable implements Runnable, MutablePairingParameters { 12 | 13 | private ContextExecutor executor; 14 | 15 | void setExecutor(ContextExecutor executor) { 16 | this.executor = executor; 17 | } 18 | 19 | public boolean containsKey(String key) { 20 | return executor.containsKey(key); 21 | } 22 | 23 | public String getString(String key) { 24 | return executor.getString(key); 25 | } 26 | 27 | public String getString(String key, String defaultValue) { 28 | return executor.getString(key, defaultValue); 29 | } 30 | 31 | public int getInt(String key) { 32 | return executor.getInt(key); 33 | } 34 | 35 | public int getInt(String key, int defaultValue) { 36 | return executor.getInt(key, defaultValue); 37 | } 38 | 39 | public BigInteger getBigInteger(String key) { 40 | return executor.getBigInteger(key); 41 | } 42 | 43 | public BigInteger getBigIntegerAt(String key, int index) { 44 | return executor.getBigIntegerAt(key, index); 45 | } 46 | 47 | public BigInteger getBigInteger(String key, BigInteger defaultValue) { 48 | return executor.getBigInteger(key, defaultValue); 49 | } 50 | 51 | public long getLong(String key) { 52 | return executor.getLong(key); 53 | } 54 | 55 | public long getLong(String key, long defaultValue) { 56 | return executor.getLong(key, defaultValue); 57 | } 58 | 59 | public byte[] getBytes(String key) { 60 | return executor.getBytes(key); 61 | } 62 | 63 | public byte[] getBytes(String key, byte[] defaultValue) { 64 | return executor.getBytes(key, defaultValue); 65 | } 66 | 67 | public String toString(String separator) { 68 | return executor.toString(separator); 69 | } 70 | 71 | public Object getObject(String key) { 72 | return executor.getObject(key); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/concurrent/recursive/RecursiveMultiplier.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.concurrent.recursive; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | 5 | import java.util.concurrent.RecursiveTask; 6 | 7 | /** 8 | * @author Angelo De Caro (jpbclib@gmail.com) 9 | * @since 2.0.0 10 | */ 11 | class RecursiveMultiplier extends RecursiveTask { 12 | private static final int SEQUENTIAL_THRESHOLD = 2; 13 | 14 | private final Element[] elements; 15 | private final int low; 16 | private final int high; 17 | 18 | private RecursiveMultiplier(Element[] elements, int lo, int hi) { 19 | this.elements = elements; 20 | this.low = lo; 21 | this.high = hi; 22 | } 23 | 24 | protected Element compute() { 25 | if (high == low) { 26 | return elements[low]; 27 | } 28 | 29 | if (high - low < SEQUENTIAL_THRESHOLD) { 30 | return elements[low].mul(elements[high]); 31 | } else { 32 | int mid = low + (high - low) / 2; 33 | 34 | RecursiveMultiplier left = new RecursiveMultiplier(elements, low, mid); 35 | RecursiveMultiplier right = new RecursiveMultiplier(elements, mid + 1, high); 36 | left.fork(); 37 | 38 | Element rightAns = right.compute(); 39 | Element leftAns = left.join(); 40 | return rightAns.mul(leftAns); 41 | } 42 | } 43 | 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/io/ExByteArrayInputStream.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.io; 2 | 3 | import java.io.ByteArrayInputStream; 4 | 5 | /** 6 | * @author Angelo De Caro (jpbclib@gmail.com) 7 | * @since 1.0.0 8 | */ 9 | class ExByteArrayInputStream extends ByteArrayInputStream { 10 | 11 | ExByteArrayInputStream(byte[] buf, int offset, int length) { 12 | super(buf, offset, length); 13 | } 14 | 15 | int getPos() { 16 | return pos; 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/io/FieldStreamReader.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.io; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | 6 | /** 7 | * @author Angelo De Caro (jpbclib@gmail.com) 8 | * @since 2.0.0 9 | */ 10 | public class FieldStreamReader { 11 | 12 | private final Field field; 13 | private final byte[] buffer; 14 | 15 | private int cursor; 16 | 17 | private final ExByteArrayInputStream bais; 18 | 19 | 20 | public FieldStreamReader(Field field, byte[] buffer, int offset) { 21 | this.field = field; 22 | this.buffer = buffer; 23 | 24 | this.cursor = offset; 25 | 26 | this.bais = new ExByteArrayInputStream(buffer, offset, buffer.length - offset); 27 | } 28 | 29 | 30 | public Element readElement() { 31 | Element element = field.newElementFromBytes(buffer, cursor); 32 | jump(field.getLengthInBytes(element)); 33 | return element; 34 | } 35 | 36 | 37 | private void jump(int length) { 38 | cursor += length; 39 | bais.skip(length); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/it/unisa/dia/gas/plaf/jpbc/util/io/PairingStreamReader.java: -------------------------------------------------------------------------------- 1 | package it.unisa.dia.gas.plaf.jpbc.util.io; 2 | 3 | import it.unisa.dia.gas.jpbc.Element; 4 | import it.unisa.dia.gas.jpbc.Field; 5 | 6 | import java.io.DataInputStream; 7 | 8 | /** 9 | * @author Angelo De Caro (jpbclib@gmail.com) 10 | * @since 2.0.0 11 | */ 12 | public class PairingStreamReader { 13 | 14 | private final byte[] buffer; 15 | 16 | private int cursor; 17 | 18 | private final DataInputStream dis; 19 | private final ExByteArrayInputStream bais; 20 | 21 | 22 | public PairingStreamReader(byte[] buffer, int offset) { 23 | this.buffer = buffer; 24 | 25 | this.cursor = offset; 26 | 27 | this.bais = new ExByteArrayInputStream(buffer, offset, buffer.length - offset); 28 | this.dis = new DataInputStream(bais); 29 | } 30 | 31 | 32 | public Element readFieldElement(Field field) { 33 | Element element = field.newElementFromBytes(buffer, cursor); 34 | jump(field.getLengthInBytes(element)); 35 | return element; 36 | } 37 | 38 | public int readInt() { 39 | try { 40 | return dis.readInt(); 41 | } catch (Exception e) { 42 | throw new RuntimeException(e); 43 | } finally { 44 | cursor = bais.getPos(); 45 | } 46 | } 47 | 48 | 49 | private void jump(int length) { 50 | cursor += length; 51 | bais.skip(length); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/a/a_181_603.properties: -------------------------------------------------------------------------------- 1 | type=a 2 | q=98826429041171753291515535532523512299028170537954154869719707264887274916552228805607584116490046284509883309001532457986879277885241872021906840932513241346999389365188296460009947 3 | h=32243626948934860887488490158437299489453513352745889246437755713701521031193083418924110592954582395114812811896992400310730276 4 | r=3064991081731777546575510593831386635550174528483098623 5 | exp2=181 6 | exp1=127 7 | sign1=-1 8 | sign0=-1 9 | -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/a1/a1.properties: -------------------------------------------------------------------------------- 1 | type a1 2 | p 48512875896303752499712277254589628516419352188294521198189567511009073158115045361294839347099315898960045398524682007334164928531594799149100548036445760110913157420655690361891290858441360807158247259460501343449199712532828063940008683740048500980441989713739689655610578458388126934242630557397618776539259 3 | n 36203638728584889925158415861634051131656232976339194924022065306723188923966451762160327870969638730567198058600508960697138006366861790409776528385407283664860565239295291314844246909284597617282274074224254733917313218308080644731349763985110821627195514711746037056425804819692632040479575042834043863089 4 | l 1340 5 | -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/a1/a1_3primes.properties: -------------------------------------------------------------------------------- 1 | type a1 2 | p 366367488891996953464177724116303745162638173687744722519198135694997143072442262495598229941717662154427658079854456489570272370616011287688607329742778102455597883634128585744719424310959317047586224681182636439016425661921690497021146700063195738002188227997783374002314458898017630781982566563893778990493498285101082603954390913195270780853594236668554376905922385386216967838757757080927927684495607763573259244032815657112318277513263692331304724597733065311 3 | n 602578106730258147145029151507078528228023311986422240985523249498350564263885300157233930825193523280308648157655356068372158504302650144224683108129569247459864940187711489711709579458814666196687869541418809932592805365002780422732149177735519305924651690785827917766964570555950050628260800269562136497522201126810991124924985054597484836930253678731174962016319712806277907629535784672578828428446723295350755335580288909724207693278394230808066981246271489 4 | n0 6703903964971298549787012499102923063739682910296196688861780721860882015036773488400937149083451713845015929093243025426876941405973284973216841682911233 5 | n1 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433644711116801 6 | n2 6703903964971298549787012499102923063739682910296196723857792318389072804996809122282878994734162608136414911905572727986124928595988056549427656871903233 7 | l 608 8 | -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/d/d_9563.properties: -------------------------------------------------------------------------------- 1 | type=d 2 | q=2094476214847295281570670320144695883131009753607350517892357 3 | n=2094476214847295281570670320143248652598286201895740019876423 4 | h=1122591 5 | r=1865751832009427548920907365321162072917283500309320153 6 | a=1600875433740386825198383431168945562270417502304239401357245 7 | b=1883770763759143784890939070283952473016424784874042280216403 8 | k=6 9 | nk=84421409121513221644716967251498543569964760150943970280296295496165154657097987617093928595467244393873913569302597521196137376192587250931727762632568620562823714441576400096248911214941742242106512149305076320555351603145285797909942596124862593877499051211952936404822228308154770272833273836975042632765377879565229109013234552083886934379264203243445590336 10 | hk=24251848326363771171270027814768648115136299306034875585195931346818912374815385257266068811350396365799298585287746735681314613260560203359251331805443378322987677594618057568388400134442772232086258797844238238645130212769322779762522643806720212266304 11 | coeff0=2065690287117609326649346584281980460557529959875694640990519 12 | coeff1=1397435662856407633647226985762280850415970662235392513127300 13 | coeff2=63493429071688899539536097280593462496131736269024343328360 14 | nqr=1909317666991039841294564035765697781775142140585159768342355 -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/e/e.properties: -------------------------------------------------------------------------------- 1 | type e 2 | q 7245986106510086080714203333362098431608853335867425877960916928496629182991629664903654100214900946450053872786629995869445693724001299041657434948257845644905153122838458864000479326695430719258600053239930483226650953770354174712511646273516974069245462534034085895319225452125649979474047163305307830001 3 | r 730750862221594424981965739670091261094297337857 4 | h 13569343110918781839835249021482970252603216587988030044836106948825516930173270978617489032334001006615524543925753725725046733884363846960470444404747241287743773746682188521738728797153760275116924829183670000 5 | a 7130970454025799000067946137594446075551569949583815943390108723282396973737794273397246892274981883807989525599540630855644968426794929215599380425269625872763801485968007136000471718335185787206876242871042697778608875139078711621836858237429403052273312335081163896980825048123655535355411494046493419999 6 | b 7169309004853894693616698536183663527570664411678352588247044791687141043489072737232715961588288238022010974661903752526911876859197052490952065266265699130144252031591491045333807587788600764557450846327338626261289568016170532652061787582791926724597362401398804563093625182790987016728290050466098223333 7 | exp2 159 8 | exp1 135 9 | sign1 1 10 | sign0 1 11 | -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/f/f.properties: -------------------------------------------------------------------------------- 1 | type f 2 | q 205523667896953300194896352429254920972540065223 3 | r 205523667896953300194895899082072403858390252929 4 | b 40218105156867728698573668525883168222119515413 5 | beta 115334401956802802075595682801335644058796914268 6 | alpha0 191079354656274778837764015557338301375963168470 7 | alpha1 71445317903696340296199556072836940741717506375 8 | -------------------------------------------------------------------------------- /src/main/resources/it/unisa/dia/gas/plaf/jpbc/pairing/g/g149.properties: -------------------------------------------------------------------------------- 1 | type g 2 | q 503189899097385532598615948567975432740967203 3 | n 503189899097385532598571084778608176410973351 4 | h 1 5 | r 503189899097385532598571084778608176410973351 6 | a 465197998498440909244782433627180757481058321 7 | b 463074517126110479409374670871346701448503064 8 | k 10 9 | nk 1040684643531490707494989587381629956832530311976146077888095795458709511789670022388326295177424065807612879371896982185473788988016190582073591316127396374860265835641044035656044524481121528846249501655527462202999638159773731830375673076317719519977183373353791119388388468745670818193868532404392452816602538968163226713846951514831917487400267590451867746120591750902040267826351982737642689423713163967384383105678367875981348397359466338807 10 | hk 4110127713690841149713310614420858884651261781185442551927080083178682965171097172366598236129731931693425629387502221804555636704708008882811353539555915064049685663790355716130262332064327767695339422323460458479884756000782939428852120522712008037615051139080628734566850259704397643028017435446110322024094259858170303605703280329322675124728639532674407 11 | coeff0 67343110967802947677845897216565803152319250 12 | coeff1 115936772834120270862756636148166314916823221 13 | coeff2 87387877425076080433559927080662339215696505 14 | coeff3 433223145899090928132052677121692683015058909 15 | coeff4 405367866213598664862417230702935310328613596 16 | nqr 22204504160560785687198080413579021865783099 17 | --------------------------------------------------------------------------------