├── .gitignore ├── LICENSE ├── MPCApplet ├── !uploader │ ├── MPCApplet.cap │ ├── gp.exe │ └── uploadMPCj.bat ├── build.bat ├── ext │ ├── ant-javacard.jar │ ├── java_card_kit-2_2_2 │ │ ├── api_export_files │ │ │ ├── java │ │ │ │ ├── io │ │ │ │ │ └── javacard │ │ │ │ │ │ └── io.exp │ │ │ │ ├── lang │ │ │ │ │ └── javacard │ │ │ │ │ │ └── lang.exp │ │ │ │ └── rmi │ │ │ │ │ └── javacard │ │ │ │ │ └── rmi.exp │ │ │ ├── javacard │ │ │ │ ├── framework │ │ │ │ │ ├── javacard │ │ │ │ │ │ └── framework.exp │ │ │ │ │ └── service │ │ │ │ │ │ └── javacard │ │ │ │ │ │ └── service.exp │ │ │ │ └── security │ │ │ │ │ └── javacard │ │ │ │ │ └── security.exp │ │ │ └── javacardx │ │ │ │ ├── apdu │ │ │ │ └── javacard │ │ │ │ │ └── apdu.exp │ │ │ │ ├── biometry │ │ │ │ └── javacard │ │ │ │ │ └── biometry.exp │ │ │ │ ├── crypto │ │ │ │ └── javacard │ │ │ │ │ └── crypto.exp │ │ │ │ ├── external │ │ │ │ └── javacard │ │ │ │ │ └── external.exp │ │ │ │ └── framework │ │ │ │ ├── math │ │ │ │ └── javacard │ │ │ │ │ └── math.exp │ │ │ │ ├── tlv │ │ │ │ └── javacard │ │ │ │ │ └── tlv.exp │ │ │ │ └── util │ │ │ │ ├── intx │ │ │ │ └── javacard │ │ │ │ │ └── intx.exp │ │ │ │ └── javacard │ │ │ │ └── util.exp │ │ ├── bin │ │ │ ├── apdutool │ │ │ ├── capdump │ │ │ ├── capgen │ │ │ ├── converter │ │ │ ├── cref │ │ │ ├── exp2text │ │ │ ├── jcwde │ │ │ ├── libjpcsclite.so │ │ │ ├── scriptgen │ │ │ ├── verifycap │ │ │ ├── verifyexp │ │ │ └── verifyrev │ │ └── lib │ │ │ ├── apduio.jar │ │ │ ├── apdutool.jar │ │ │ ├── api.jar │ │ │ ├── api_16.jar │ │ │ ├── capdump.jar │ │ │ ├── converter.jar │ │ │ ├── installer.jar │ │ │ ├── javacardframework.jar │ │ │ ├── jcclientsamples.jar │ │ │ ├── jcrmiclientframework.jar │ │ │ ├── jcwde.jar │ │ │ ├── jcwde_16.jar │ │ │ ├── offcardverifier.jar │ │ │ └── scriptgen.jar │ └── java_card_kit-3_0_3 │ │ ├── COPYRIGHT.html │ │ ├── api_export_files │ │ ├── java │ │ │ ├── io │ │ │ │ └── javacard │ │ │ │ │ └── io.exp │ │ │ ├── lang │ │ │ │ └── javacard │ │ │ │ │ └── lang.exp │ │ │ └── rmi │ │ │ │ └── javacard │ │ │ │ └── rmi.exp │ │ ├── javacard │ │ │ ├── framework │ │ │ │ ├── javacard │ │ │ │ │ └── framework.exp │ │ │ │ └── service │ │ │ │ │ └── javacard │ │ │ │ │ └── service.exp │ │ │ └── security │ │ │ │ └── javacard │ │ │ │ └── security.exp │ │ └── javacardx │ │ │ ├── apdu │ │ │ └── javacard │ │ │ │ └── apdu.exp │ │ │ ├── biometry │ │ │ └── javacard │ │ │ │ └── biometry.exp │ │ │ ├── crypto │ │ │ └── javacard │ │ │ │ └── crypto.exp │ │ │ ├── external │ │ │ └── javacard │ │ │ │ └── external.exp │ │ │ └── framework │ │ │ ├── math │ │ │ └── javacard │ │ │ │ └── math.exp │ │ │ ├── tlv │ │ │ └── javacard │ │ │ │ └── tlv.exp │ │ │ └── util │ │ │ ├── intx │ │ │ └── javacard │ │ │ │ └── intx.exp │ │ │ └── javacard │ │ │ └── util.exp │ │ ├── legal │ │ ├── Distribution_ReadME.txt │ │ └── THIRDPARTYREADME.txt │ │ ├── lib │ │ ├── api_classic.jar │ │ ├── api_connected.jar │ │ ├── logging.properties │ │ └── tools.jar │ │ └── shared │ │ ├── Java_clr_hori.gif │ │ ├── Java_clr_hori_interval.gif │ │ ├── Java_clr_hori_small.gif │ │ ├── downicon.gif │ │ ├── oracle.gif │ │ ├── smallOracleLogo.gif │ │ └── topicon.gif ├── jcbuild.xml └── src │ └── mpc │ ├── Consts.java │ ├── ECPointBase.java │ ├── ECPointBuilder.java │ ├── ECPoint_SW.java │ ├── MPCApplet.java │ ├── MPCCryptoOps.java │ ├── PM.java │ ├── QuorumContext.java │ ├── ReturnCodes.java │ ├── StateModel.java │ └── jcmathlib.java ├── MPCTestClient ├── build.xml ├── dist │ └── README.TXT ├── libs │ ├── bcprov-jdk15on-155.jar │ ├── bignat.jar │ ├── jcardsim-3.0.5-SNAPSHOT.jar │ └── offcard.jar ├── src │ └── mpctestclient │ │ ├── CardMPCPlayer.java │ │ ├── CardManagement.java │ │ ├── MPCGlobals.java │ │ ├── MPCPlayer.java │ │ ├── MPCRunConfig.java │ │ ├── MPCTestClient.java │ │ ├── SimulatedCard.java │ │ ├── SimulatedCardChannelLocal.java │ │ ├── SimulatedMPCPlayer.java │ │ └── Util.java └── test │ ├── mpc │ └── BignatTests.java │ └── mpcclient │ └── MPCProtocolTests.java └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | #*.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | 24 | /MPCTestClient/dist/ 25 | /MPCTestClient/build/ 26 | /MPCTestClient/nbproject/ 27 | /MPCTestClient/MPC_PERF_log_* 28 | /MPCTestClient/MPC_DETAILPERF_log_* 29 | /MPCTestClient/TRAP_RAW* 30 | 31 | /experiments/ 32 | /MystClient/nbproject/private/ 33 | /MystHost/build/ 34 | /MystHost/dist/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Petr Svenda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MPCApplet/!uploader/MPCApplet.cap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/!uploader/MPCApplet.cap -------------------------------------------------------------------------------- /MPCApplet/!uploader/gp.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/!uploader/gp.exe -------------------------------------------------------------------------------- /MPCApplet/!uploader/uploadMPCj.bat: -------------------------------------------------------------------------------- 1 | java -jar gp.jar -uninstall MPCApplet.cap 2 | 3 | java -jar gp.jar -install MPCApplet.cap -verbose -d 4 | 5 | java -jar gp.jar -l 6 | 7 | java -noverify -jar MPCTestClient.jar 8 | 9 | -------------------------------------------------------------------------------- /MPCApplet/build.bat: -------------------------------------------------------------------------------- 1 | ant -f jcbuild.xml build 2 | -------------------------------------------------------------------------------- /MPCApplet/ext/ant-javacard.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/ant-javacard.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/java/io/javacard/io.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/java/io/javacard/io.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/java/lang/javacard/lang.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/java/lang/javacard/lang.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/java/rmi/javacard/rmi.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/java/rmi/javacard/rmi.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacard/framework/javacard/framework.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacard/framework/javacard/framework.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacard/framework/service/javacard/service.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacard/framework/service/javacard/service.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacard/security/javacard/security.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacard/security/javacard/security.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/apdu/javacard/apdu.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/apdu/javacard/apdu.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/biometry/javacard/biometry.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/biometry/javacard/biometry.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/crypto/javacard/crypto.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/crypto/javacard/crypto.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/external/javacard/external.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/external/javacard/external.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/math/javacard/math.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/math/javacard/math.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/tlv/javacard/tlv.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/tlv/javacard/tlv.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/util/intx/javacard/intx.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/util/intx/javacard/intx.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/api_export_files/javacardx/framework/util/javacard/util.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/apdutool: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.apdutool.Main "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/capdump: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.capdump.CapDump "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/capgen: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.jcasm.cap.Main "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/converter: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.converter.Converter "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/cref: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/bin/cref -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/exp2text: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.converter.Exp2Text "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/jcwde: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.jcwde.Main "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/libjpcsclite.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/bin/libjpcsclite.so -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/scriptgen: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.scriptgen.Main "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/verifycap: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.offcardverifier.Verifier "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/verifyexp: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.offcardverifier.VerifyExp "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/bin/verifyrev: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2005 Sun Microsystems, Inc. All rights reserved. 4 | # Use is subject to license terms. 5 | # 6 | 7 | JAVA_HOME=${JAVA_HOME:-/usr/j2se} 8 | 9 | bin_home=`dirname $0` 10 | JC_HOME=${JC_HOME:-$bin_home/..} 11 | 12 | JC_PATH=$JC_HOME/lib/apdutool.jar:$JC_HOME/lib/apduio.jar:$JC_HOME/lib/converter.jar:$JC_HOME/lib/jcwde.jar:$JC_HOME/lib/scriptgen.jar:$JC_HOME/lib/offcardverifier.jar:$JC_HOME/lib/api.jar:$JC_HOME/lib/installer.jar:$JC_HOME/lib/capdump.jar:$JC_HOME/samples/classes:$CLASSPATH 13 | 14 | JFLAGS="-classpath $JC_PATH" 15 | $JAVA_HOME/bin/java $JFLAGS com.sun.javacard.offcardverifier.VerifyRev "$@" 16 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/apduio.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/apduio.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/apdutool.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/apdutool.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/api.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/api.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/api_16.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/api_16.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/capdump.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/capdump.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/converter.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/converter.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/installer.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/installer.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/javacardframework.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/javacardframework.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/jcclientsamples.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/jcclientsamples.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/jcrmiclientframework.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/jcrmiclientframework.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/jcwde.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/jcwde.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/jcwde_16.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/jcwde_16.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/offcardverifier.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/offcardverifier.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-2_2_2/lib/scriptgen.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-2_2_2/lib/scriptgen.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/COPYRIGHT.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | Copyright 12 | 13 | 14 |
Copyright © 1998, 2010, 15 | Oracle and/or its affiliates. All rights reserved.
17 |
18 |

This software and related documentation are provided under a license 19 | agreement containing restrictions on use and disclosure and are 20 | protected by intellectual property laws. Except as expressly permitted 21 | in your license agreement or allowed by law, you may not use, copy, 22 | reproduce, translate, broadcast, modify, license, transmit, distribute, 23 | exhibit, perform, publish, or display any part, in any form, or by any 24 | means. Reverse engineering, disassembly, or decompilation of this 25 | software, unless required by law for interoperability, is prohibited.

26 |

The information contained herein is subject to change without notice 27 | and is not warranted to be error-free. If you find any errors, please 28 | report them to us in writing.

29 |

If this is software or related software documentation that is 30 | delivered to the U.S. Government or anyone licensing it on behalf of 31 | the U.S. Government, the following notice is applicable:

32 |

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related 33 | documentation and technical data delivered to U.S. Government customers 34 | are "commercial computer software" or "commercial technical data" 35 | pursuant to the applicable Federal Acquisition Regulation and 36 | agency-specific supplemental regulations. As such, the use, 37 | duplication, disclosure, modification, and adaptation shall be subject 38 | to the restrictions and license terms set forth in the applicable 39 | Government contract, and, to the extent applicable by the terms of the 40 | Government contract, the additional rights set forth in FAR 52.227-19, 41 | Commercial Computer Software License (December 2007). Oracle USA, Inc., 42 | 500 Oracle Parkway, Redwood City, CA 94065.

43 |

This software or hardware is developed for general use in a variety 44 | of information management applications. It is not developed or intended 45 | for use in any inherently dangerous applications, including 46 | applications which may create a risk of personal injury. If you use 47 | this software or hardware in dangerous applications, then you shall be 48 | responsible to take all appropriate fail-safe, backup, redundancy, and 49 | other measures to ensure the safe use. Oracle Corporation and its 50 | affiliates disclaim any liability for any damages caused by use of this 51 | software or hardware in dangerous applications.

52 |

Oracle and Java are registered trademarks of Oracle Corporation 53 | and/or its 54 | affiliates. Oracle and Java are registered trademarks of Oracle and/or 55 | its affiliates. Other names may be trademarks of their respective 56 | owners.

57 |

AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks 58 | or registered trademarks of Advanced Micro Devices. Intel and Intel 59 | Xeon are trademarks or registered trademarks of Intel Corporation. All 60 | SPARC trademarks are used under license and are trademarks or 61 | registered trademarks of SPARC International, Inc. UNIX is a registered 62 | trademark licensed through X/Open Company, Ltd.

63 |

This software or hardware and documentation may provide access to or 64 | information on content, products, and services from third parties. 65 | Oracle Corporation and its affiliates are not responsible for and 66 | expressly disclaim all warranties of any kind with respect to 67 | third-party content, products, and services. Oracle Corporation and its 68 | affiliates will not be responsible for any loss, costs, or damages 69 | incurred due to your access to or use of third-party content, products, 70 | or services.
71 |

72 |
73 | Copyright © 1998, 2010, Oracle 74 | et/ou ses affiliés. 75 | Tous droits réservés. 76 | 77 |

Ce logiciel et la documentation qui l’accompagne sont 78 | protégés par les 79 | lois sur la propriété intellectuelle. Ils sont 80 | concédés sous licence et soumis à 81 | des restrictions d’utilisation et de divulgation. Sauf disposition de 82 | votre contrat de licence ou 83 | de la loi, vous ne pouvez pas copier, reproduire, traduire, diffuser, 84 | modifier, breveter, 85 | transmettre, distribuer, exposer, exécuter, publier ou afficher 86 | le logiciel, même partiellement, sous quelque forme 87 | et par quelque procédé que ce soit. Par ailleurs, il est 88 | interdit de 89 | procéder à toute ingénierie inverse du logiciel, 90 | de le désassembler ou de le décompiler, 91 | excepté à des fins d’interopérabilité avec 92 | des logiciels tiers ou tel que prescrit par 93 | la loi.

94 |

Les informations fournies dans ce document sont susceptibles de 95 | modification sans préavis. 96 | Par ailleurs, Oracle Corporation ne garantit pas qu’elles soient 97 | exemptes d’erreurs et vous invite, 98 | le cas échéant, à lui en faire part par 99 | écrit.

100 |

Si ce logiciel, ou 101 | la documentation qui l’accompagne, est concédé sous 102 | licence au Gouvernement des Etats-Unis, ou à 103 | toute entité qui délivre la licence de ce logiciel ou 104 | l’utilise pour le 105 | compte du Gouvernement des Etats-Unis, la notice suivante s’applique:

106 |

U.S. GOVERNMENT RIGHTS. Programs, 107 | software, databases, and related documentation and technical data 108 | delivered to U.S. Government customers are 109 | "commercial computer software" or "commercial technical data" pursuant 110 | to the applicable Federal Acquisition 111 | Regulation and agency-specific supplemental regulations. As such, the 112 | use, duplication, disclosure, modification, and 113 | adaptation shall be subject to the restrictions and license terms set 114 | forth in 115 | the applicable Government contract, and, to the extent applicable by 116 | the terms of the 117 | Government contract, the additional rights set forth in FAR 52.227-19, 118 | Commercial Computer Software 119 | License (December 2007). Oracle America, Inc., 500 Oracle Parkway, 120 | Redwood City, CA 121 | 94065.

122 |

Ce logiciel ou matériel a été 123 | développé pour un usage général dans le 124 | cadre d’applications de gestion des informations. Ce logiciel ou 125 | matériel n’est pas conçu ni 126 | n’est destiné à être utilisé dans des 127 | applications à risque, notamment dans des applications 128 | pouvant causer des dommages corporels. Si vous utilisez ce logiciel ou 129 | matériel dans 130 | le cadre d’applications dangereuses, il est de votre 131 | responsabilité de prendre toutes les mesures 132 | de secours, de sauvegarde, de redondance et autres mesures 133 | nécessaires à son utilisation 134 | dans des conditions optimales de sécurité. Oracle 135 | Corporation et ses affiliés déclinent toute 136 | responsabilité 137 | quant aux dommages causés par l’utilisation de ce logiciel ou 138 | matériel pour ce type 139 | d’applications.

140 |

Oracle et Java sont des marques déposées d’Oracle 141 | Corporation et/ou de ses affiliés.Tout 142 | autre nom mentionné peut correspondre à des marques 143 | appartenant à d’autres propriétaires qu’Oracle.

144 |

AMD, Opteron, 145 | le logo AMD et le logo AMD Opteron sont des marques ou des 146 | marques déposées d’Advanced Micro Devices. Intel et Intel 147 | Xeon sont des marques ou 148 | des marques déposées d’Intel Corporation. Toutes les 149 | marques SPARC sont utilisées sous licence et 150 | sont des marques ou des marques déposées de SPARC 151 | International, Inc. UNIX est une 152 | marque déposée concédée sous licence par 153 | X/Open Company, Ltd.

154 |

Ce logiciel ou matériel et 155 | la documentation qui l’accompagne peuvent fournir des informations ou 156 | des liens donnant accès à 157 | des contenus, des produits et des services émanant de tiers. 158 | Oracle Corporation et 159 | ses affiliés déclinent toute responsabilité ou 160 | garantie expresse quant aux contenus, produits ou services 161 | émanant de tiers. En aucun cas, Oracle Corporation et ses 162 | affiliés ne sauraient 163 | être tenus pour responsables des pertes subies, des coûts 164 | occasionnés ou des dommages causés 165 | par l’accès à des contenus, produits ou services tiers, 166 | ou à leur utilisation.
167 |

168 |

169 |
170 | 171 | 172 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/java/io/javacard/io.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/java/io/javacard/io.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/java/lang/javacard/lang.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/java/lang/javacard/lang.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/java/rmi/javacard/rmi.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/java/rmi/javacard/rmi.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacard/framework/javacard/framework.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacard/framework/javacard/framework.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacard/framework/service/javacard/service.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacard/framework/service/javacard/service.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacard/security/javacard/security.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacard/security/javacard/security.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/apdu/javacard/apdu.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/apdu/javacard/apdu.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/biometry/javacard/biometry.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/biometry/javacard/biometry.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/crypto/javacard/crypto.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/crypto/javacard/crypto.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/external/javacard/external.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/external/javacard/external.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/math/javacard/math.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/math/javacard/math.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/tlv/javacard/tlv.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/tlv/javacard/tlv.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/util/intx/javacard/intx.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/util/intx/javacard/intx.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/util/javacard/util.exp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/api_export_files/javacardx/framework/util/javacard/util.exp -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/legal/Distribution_ReadME.txt: -------------------------------------------------------------------------------- 1 | DistributionREADME 2 | 3 | DISTRIBUTION BY DEVELOPERS. Subject to the terms and conditions of the Software License Agreement and the obligations, restrictions, and exceptions set forth below, You may reproduce and distribute the portions of Software identified below ("Redistributable"), provided that: 4 | 5 | (a) You distribute Redistributable complete and unmodified and only bundled as part of Your Programs, 6 | 7 | (b) Your Programs add significant and primary functionality to the Redistributable, 8 | 9 | (c) You do not distribute additional software intended to replace any 10 | component(s) of the Redistributable, 11 | 12 | (d) You do not remove or alter any proprietary legends or notices contained in or on the Redistributable. 13 | 14 | (e) You only distribute the Redistributable subject to a license agreement that protects Oracle's interests consistent with the terms contained in this 15 | Agreement, and 16 | 17 | (f) You agree to defend and indemnify Oracle and its licensors from and against any damages, costs, liabilities, settlement amounts and/or expenses (including attorneys' fees) incurred in connection with any claim, lawsuit or action by any third party that arises or results from the use or distribution of any and all Programs and/or Redistributable. 18 | 19 | The following files are Redistributables: 20 | 21 | Java Card Development Kit 3.0.3 22 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/lib/api_classic.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/lib/api_classic.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/lib/api_connected.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/lib/api_connected.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/lib/logging.properties: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved. 2 | 3 | # Properties file which configures the operation of the JDK 4 | # logging facility. 5 | 6 | # The system will look for this config file, first using 7 | # a System property specified at startup: 8 | # 9 | # >java -Djava.util.logging.config.file=myLoggingConfigFilePath 10 | # 11 | # If this property is not specified, then the config file is 12 | # retrieved from its default location at: 13 | # 14 | # JDK_HOME/jre/lib/logging.properties 15 | 16 | # Global logging properties. 17 | # ------------------------------------------ 18 | # The set of handlers to be loaded upon startup. 19 | # Comma-separated list of class names. 20 | # java.util.logging.ConsoleHandler 21 | handlers=com.sun.javacard.tools.util.JCConsoleHandler, java.util.logging.FileHandler 22 | 23 | # Default global logging level. 24 | # Loggers and Handlers may override this level 25 | .level=ALL 26 | 27 | # Loggers 28 | # ------------------------------------------ 29 | # Loggers are usually attached to packages. 30 | # Here, the level for each package is specified. 31 | # The global level is used by default, so levels 32 | # specified here simply act as an override. 33 | #com.sun.javacard.offcardinstaller=ALL 34 | 35 | # Handlers 36 | # ----------------------------------------- 37 | 38 | com.sun.javacard.tools.util.JCConsoleHandler.level=ALL 39 | com.sun.javacard.tools.util.JCConsoleHandler.formatter=com.sun.javacard.tools.util.JCToolsFormatter 40 | com.sun.javacard.tools.util.JCConsoleHandler.filter=com.sun.javacard.tools.util.ConsoleFilter 41 | 42 | # --- FileHandler --- 43 | # Override of global logging level 44 | java.util.logging.FileHandler.level=ALL 45 | 46 | # Naming style for the output file: 47 | # (The output file is placed in the directory 48 | # defined by the "user.home" System property.) 49 | java.util.logging.FileHandler.pattern=%h/java%u.log 50 | 51 | # Limiting size of output file in bytes: 52 | java.util.logging.FileHandler.limit=50000 53 | 54 | # Number of output files to cycle through, by appending an 55 | # integer to the base file name: 56 | java.util.logging.FileHandler.count=10 57 | 58 | # Style of output (Simple or XML): 59 | java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter 60 | 61 | java.util.logging.FileHandler.append=true 62 | 63 | #--------------print class method info 64 | printCurrentClassAndMethod = false 65 | -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/lib/tools.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/lib/tools.jar -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/Java_clr_hori.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/Java_clr_hori.gif -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/Java_clr_hori_interval.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/Java_clr_hori_interval.gif -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/Java_clr_hori_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/Java_clr_hori_small.gif -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/downicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/downicon.gif -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/oracle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/oracle.gif -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/smallOracleLogo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/smallOracleLogo.gif -------------------------------------------------------------------------------- /MPCApplet/ext/java_card_kit-3_0_3/shared/topicon.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCApplet/ext/java_card_kit-3_0_3/shared/topicon.gif -------------------------------------------------------------------------------- /MPCApplet/jcbuild.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/Consts.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | /** 4 | * 5 | * @author Petr Svenda 6 | */ 7 | public class Consts { 8 | // Manually updated version of corresponding git commit 9 | public final static byte[] GIT_COMMIT_MANUAL = {(byte) 0x01, (byte) 0x14, (byte) 0x20, (byte) 0xaf}; 10 | 11 | // MAIN INSTRUCTION CLASS 12 | public final static byte CLA_MPC = (byte) 0xB0; 13 | 14 | // INStructions 15 | // Card Management 16 | 17 | public final static byte INS_QUORUM_SETUP_NEW = (byte) 0x01; 18 | public final static byte INS_PERSONALIZE_GETCARDINFO = (byte) 0x02; 19 | public final static byte INS_QUORUM_RESET = (byte) 0x03; 20 | public final static byte INS_PERF_SETSTOP = (byte) 0x04; 21 | public final static byte INS_SET_BACKDOORED_EXAMPLE = (byte) 0x05; 22 | public final static byte INS_TESTECC = (byte) 0x06; 23 | public final static byte INS_QUORUM_REMOVE = (byte) 0x07; 24 | 25 | public final static byte INS_PERSONALIZE_INITIALIZE = (byte) 0x08; 26 | public final static byte INS_PERSONALIZE_SET_USER_AUTH_PUBKEY = (byte) 0x09; 27 | 28 | 29 | 30 | 31 | 32 | // KeyGen Operations 33 | public final static byte INS_KEYGEN_INIT = (byte) 0x10; 34 | public final static byte INS_KEYGEN_RETRIEVE_COMMITMENT = (byte) 0x11; 35 | public final static byte INS_KEYGEN_STORE_COMMITMENT = (byte) 0x12; 36 | public final static byte INS_KEYGEN_STORE_PUBKEY = (byte) 0x13; 37 | public final static byte INS_KEYGEN_RETRIEVE_PUBKEY = (byte) 0x14; 38 | public final static byte BUGBUG_INS_KEYGEN_RETRIEVE_PRIVKEY = (byte) 0x15; 39 | public final static byte INS_KEYGEN_RETRIEVE_AGG_PUBKEY = (byte) 0x16; 40 | 41 | public final static byte INS_KEYPROPAGATION_RETRIEVE_PRIVKEY_SHARES = (byte) 0x20; 42 | public final static byte INS_KEYPROPAGATION_SET_PRIVKEY_SHARES = (byte) 0x21; 43 | public final static byte INS_KEYPROPAGATION_RECONSTRUCT_PRIVATEKEY = (byte) 0x22; 44 | 45 | 46 | // Encryption/Decryption Operations 47 | public final static byte INS_ENCRYPT = (byte) 0x50; 48 | public final static byte INS_DECRYPT = (byte) 0x51; 49 | 50 | 51 | public final static byte INS_GENERATE_RANDOM = (byte) 0x55; 52 | 53 | // Signing Operations 54 | // 0x60 to 0x6F and 0x90 to 0x9F are not allowed according to ISO 7816-3 and -4 55 | //public final static byte INS_SIGN_INIT = (byte) 0x70; 56 | //public final static byte INS_SIGN_RETRIEVE_HASH = (byte) 0x71; 57 | //public final static byte INS_SIGN_STORE_HASH = (byte) 0x72; 58 | //public final static byte INS_SIGN_STORE_RI = (byte) 0x73; 59 | //public final static byte INS_SIGN_STORE_RI_N_HASH = (byte) 0x74; 60 | public final static byte INS_SIGN_RETRIEVE_RI = (byte) 0x75; 61 | //public final static byte INS_SIGN_RETRIEVE_RI_N_HASH = (byte) 0x76; 62 | //public final static byte BUGBUG_INS_SIGN_RETRIEVE_KI = (byte) 0x77; // BUGBUG: only for testing, remove 63 | //public final static byte BUGBUG_INS_SIGN_RETRIEVE_R = (byte) 0x78; // BUGBUG: only for testing, remove 64 | public final static byte INS_SIGN = (byte) 0x79; 65 | public final static byte INS_SIGN_GET_CURRENT_COUNTER = (byte) 0x7a; 66 | 67 | 68 | //Low level Operations 69 | public final static byte INS_ADDPOINTS = (byte) 0x80; 70 | 71 | // Custom error response codes 72 | public static final short SW_SUCCESS = (short) 0x9000; 73 | public static final short SW_TOOMANYPLAYERS = (short) 0x8000; 74 | public static final short SW_INCORRECTSTATE = (short) 0x8001; 75 | public static final short SW_INVALIDCOMMITMENT = (short) 0x8002; 76 | public static final short SW_INVALIDYSHARE = (short) 0x8003; 77 | public static final short SW_SHAREALREADYSTORED = (short) 0x8004; 78 | public static final short SW_CANTALLOCATE_BIGNAT = (short) 0x8005; 79 | public static final short SW_INVALIDPOINTTYPE = (short) 0x8006; 80 | public static final short SW_NOTSUPPORTEDYET = (short) 0x8007; 81 | public static final short SW_INTERNALSTATEMISMATCH = (short) 0x8008; 82 | public static final short SW_INVALIDPLAYERINDEX = (short) 0x8009; 83 | public static final short SW_UNKNOWNSTATE = (short) 0x800a; 84 | public static final short SW_UNKNOWNFUNCTION = (short) 0x800b; 85 | public static final short SW_COMMITMENTALREADYSTORED = (short) 0x800c; 86 | public static final short SW_INCORRECTSTATETRANSITION = (short) 0x800d; 87 | public static final short SW_FUNCTINNOTALLOWED = (short) 0x800e; 88 | public static final short SW_INVALIDPACKETSTRUCTURE = (short) 0x800d; 89 | public static final short SW_INVALIDQUORUMINDEX = (short) 0x800e; 90 | public static final short SW_INVALIDCOMMITMENTLENGTH = (short) 0x800f; 91 | public static final short SW_INVALIDMESSAGELENGTH = (short) 0x8010; 92 | public static final short SW_INVALIDCOUNTER = (short) 0x8011; 93 | public static final short SW_INCORRECTJCMATHLIBSETTINGS = (short) 0x8012; 94 | 95 | 96 | public static final short SIGN_COUNTER_LENGTH = (short) 2; 97 | 98 | 99 | 100 | public static final short PACKET_PARAMS_OPCODE_OFFSET = (short) 0; 101 | public static final short PACKET_PARAMS_LENGTH_OFFSET = (short) (PACKET_PARAMS_OPCODE_OFFSET + 1); 102 | public static final short PACKET_PARAMS_CTXINDEX_OFFSET = (short) (PACKET_PARAMS_LENGTH_OFFSET + 2); 103 | 104 | // SetupNewQuorum params 105 | public static final short PACKET_PARAMS_SETUPNEWQUORUM_NUMPLAYERS_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 106 | public static final short PACKET_PARAMS_SETUPNEWQUORUM_THISPLAYERINDEX_OFFSET = (short) (PACKET_PARAMS_SETUPNEWQUORUM_NUMPLAYERS_OFFSET + 2); 107 | // KeyGen_StoreCommitment params 108 | public static final short PACKET_PARAMS_KEYGENSTORECOMMITMENT_PLAYERID_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 109 | public static final short PACKET_PARAMS_KEYGENSTORECOMMITMENT_COMMITMENTLENGTH_OFFSET = (short) (PACKET_PARAMS_KEYGENSTORECOMMITMENT_PLAYERID_OFFSET + 2); 110 | public static final short PACKET_PARAMS_KEYGENSTORECOMMITMENT_COMMITMENT_OFFSET = (short) (PACKET_PARAMS_KEYGENSTORECOMMITMENT_COMMITMENTLENGTH_OFFSET + 2); 111 | // KeyGen_StorePublicKey params 112 | public static final short PACKET_PARAMS_KEYGENSTOREPUBKEY_PLAYERID_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 113 | public static final short PACKET_PARAMS_KEYGENSTOREPUBKEY_PUBKEYLENGTH_OFFSET = (short) (PACKET_PARAMS_KEYGENSTOREPUBKEY_PLAYERID_OFFSET + 2); 114 | public static final short PACKET_PARAMS_KEYGENSTOREPUBKEY_PUBKEY_OFFSET = (short) (PACKET_PARAMS_KEYGENSTOREPUBKEY_PUBKEYLENGTH_OFFSET + 2); 115 | // EncryptData params 116 | public static final short PACKET_PARAMS_ENCRYPT_DATALENGTH_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 117 | public static final short PACKET_PARAMS_ENCRYPT_DATA_OFFSET = (short) (PACKET_PARAMS_ENCRYPT_DATALENGTH_OFFSET + 2); 118 | // DecryptData params 119 | public static final short PACKET_PARAMS_DECRYPT_DATALENGTH_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 120 | public static final short PACKET_PARAMS_DECRYPT_DATA_OFFSET = (short) (PACKET_PARAMS_DECRYPT_DATALENGTH_OFFSET + 2); 121 | // Sign_RetrieveRandomRi params 122 | public static final short PACKET_PARAMS_SIGNRETRIEVERI_COUNTER_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 123 | // Sign_RetrieveRandomRi params 124 | public static final short PACKET_PARAMS_SIGN_COUNTER_OFFSET = (short) (PACKET_PARAMS_CTXINDEX_OFFSET + 2); 125 | //public static final short PACKET_PARAMS_SIGN_COUNTER_OFFSET = (short) (PACKET_PARAMS_SIGN_COUNTERLENGTH_OFFSET + 2); 126 | public static final short PACKET_PARAMS_SIGN_DATALENGTH_OFFSET = (short) (PACKET_PARAMS_SIGN_COUNTER_OFFSET + SIGN_COUNTER_LENGTH); 127 | public static final short PACKET_PARAMS_SIGN_DATA_OFFSET = (short) (PACKET_PARAMS_SIGN_DATALENGTH_OFFSET + 2); 128 | 129 | // Performance-related debugging response codes 130 | public static final short PERF_DECRYPT = (short) 0x7770; 131 | public static final short PERF_ENCRYPT = (short) 0x6660; 132 | public static final short PERF_SIGN = (short) 0x5550; 133 | 134 | // Global applet settings 135 | public static final short MAX_NUM_PLAYERS = (short) 15; // Maximum number of allowed players 136 | 137 | public final static boolean COMPUTE_Y_ONTHEFLY = true; // on-the-fly computation of aggregated pulic key is only option 138 | public final static boolean PLAYERS_IN_RAM = true; // if true, player (participant) info is stored in RAM => faster, consuming RAM and will NOT survive card reset 139 | public final static boolean IS_BACKDOORED_EXAMPLE = false; // if true, then applet will not follow protocol but generates backdoored applet instead 140 | 141 | 142 | // TLV types 143 | public final static byte TLV_TYPE_CARDUNIQUEDID = (byte) 0x40; 144 | public final static byte TLV_TYPE_KEYPAIR_STATE = (byte) 0x41; 145 | public final static byte TLV_TYPE_EPHIMERAL_STATE = (byte) 0x42; 146 | public final static byte TLV_TYPE_MEMORY = (byte) 0x43; 147 | public final static byte TLV_TYPE_COMPILEFLAGS = (byte) 0x44; 148 | public final static byte TLV_TYPE_GITCOMMIT = (byte) 0x45; 149 | public final static byte TLV_TYPE_EXAMPLEBACKDOOR = (byte) 0x46; 150 | public final static byte TLV_TYPE_MPCINPUTPACKET = (byte) 0x47; 151 | public final static byte TLV_TYPE_CARDINDEX = (byte) 0x48; 152 | 153 | // Lengths 154 | public static final byte CARD_ID_LONG_LENGTH = (byte) 16; // Length of unique card ID generated during applet install 155 | 156 | public static final short BASIC_ECC_LENGTH = (short) 32; // 32 => 256b ECC 157 | public static final short SHARE_BASIC_SIZE = BASIC_ECC_LENGTH; 158 | public static final short SHARE_DOUBLE_SIZE = (short) (2 * SHARE_BASIC_SIZE); // intermediate result of multiplication operation with shares (double bit length) 159 | public static final short SHARE_DOUBLE_SIZE_CARRY = (short) (SHARE_DOUBLE_SIZE + 1); // double intermediate result + 1 byte carry 160 | public static final short PUBKEY_YS_SHARE_SIZE = SHARE_DOUBLE_SIZE_CARRY; // double intermediate result + 1 byte carry 161 | public static final short SECRET_SEED_SIZE = BASIC_ECC_LENGTH; 162 | 163 | 164 | public static final short MAX_QUORUMS = 1; // Maximum number of separate quorums this card can participate in 165 | 166 | } 167 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/ECPointBase.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.framework.ISOException; 4 | import javacard.framework.JCSystem; 5 | import javacard.security.CryptoException; 6 | import javacard.security.ECKey; 7 | import javacard.security.ECPrivateKey; 8 | import javacard.security.KeyAgreement; 9 | import javacard.security.KeyPair; 10 | import mpc.jcmathlib.*; 11 | /** 12 | * 13 | * @author Vasilios Mavroudis and Petr Svenda 14 | */ 15 | public class ECPointBase implements javacard.security.ECKey { 16 | static KeyAgreement ECMultiplHelper = null; 17 | static KeyAgreement ECMultiplHelperDecrypt = null; 18 | 19 | static KeyPair disposable_pair = null; 20 | static ECPrivateKey disposable_priv = null; 21 | static KeyPair disposable_pairDecrypt = null; 22 | static ECPrivateKey disposable_privDecrypt = null; 23 | 24 | static ECCurve theCurve; 25 | 26 | static byte[] TempBuffer65 = null; 27 | static byte[] pt_A_arr = null; // Check if can share with TempBuffer65 28 | static byte[] pointTpmArray = null; // Check if can share with TempBuffer65 29 | 30 | 31 | static void allocate(ECCurve curve) { 32 | theCurve = curve; 33 | disposable_pair = theCurve.newKeyPair(disposable_pair); 34 | disposable_priv = (ECPrivateKey) disposable_pair.getPrivate(); 35 | disposable_pair.genKeyPair(); 36 | disposable_pairDecrypt = theCurve.newKeyPair(disposable_pairDecrypt); 37 | disposable_privDecrypt = (ECPrivateKey) disposable_pairDecrypt.getPrivate(); 38 | disposable_pairDecrypt.genKeyPair(); 39 | 40 | TempBuffer65 = JCSystem.makeTransientByteArray(Consts.SHARE_DOUBLE_SIZE_CARRY, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 41 | pointTpmArray = JCSystem.makeTransientByteArray(Consts.SHARE_DOUBLE_SIZE_CARRY, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 42 | pt_A_arr = JCSystem.makeTransientByteArray(Consts.SHARE_DOUBLE_SIZE_CARRY, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 43 | } 44 | 45 | public void initializeECPoint_SecP256r1() { 46 | this.setFieldFP(SecP256r1.p, (short) 0, (short) SecP256r1.p.length); 47 | this.setA(SecP256r1.a, (short) 0, (short) SecP256r1.a.length); 48 | this.setB(SecP256r1.b, (short) 0, (short) SecP256r1.b.length); 49 | this.setG(SecP256r1.G, (short) 0, (short) SecP256r1.G.length); 50 | this.setR(SecP256r1.r, (short) 0, (short) SecP256r1.r.length); 51 | } 52 | 53 | public void setW(byte[] g, short gOffset, short gLen) { 54 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 55 | } 56 | 57 | public short getW(byte[] g, short gOffset) { 58 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 59 | return -1; 60 | } 61 | 62 | public short ScalarMultiplication(ECPointBase BasePoint, KeyAgreement ecKeyAgreement, byte[] result) { 63 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 64 | return -1; 65 | } 66 | public short ScalarMultiplication(byte[] BasePoint, short BasePointOffset, short BasePointLen, byte[] value, byte[] result) { 67 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 68 | return -1; 69 | } 70 | public void ScalarMultiplication(ECPointBase BasePoint, KeyAgreement ecKeyAgreement, ECPointBase ResultECPoint) { 71 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 72 | } 73 | public short ScalarMultiplication(byte[] BasePoint, short BasePointOffset, short BasePointLen, KeyAgreement ecKeyAgreement, byte[] result) { 74 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 75 | return -1; 76 | } 77 | public void ScalarMultiplication(ECPointBase BasePoint, byte[] value, ECPointBase ResultECPoint) { 78 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 79 | } 80 | public short ScalarMultiplication(ECPointBase BasePoint, byte[] value, byte[] result) { 81 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 82 | return -1; 83 | } 84 | 85 | 86 | 87 | 88 | public static void ECPointAddition(ECPointBase PointA, ECPointBase PointB, ECPointBase ResultECPoint) { 89 | PointB.getW(pointTpmArray, (short) 0); 90 | ECPointAddition(PointA, pointTpmArray, (short) 0, ResultECPoint); 91 | } 92 | 93 | public static void ECPointAddition(ECPointBase PointA, byte[] PointB, ECPointBase ResultECPoint) { 94 | ECPointAddition(PointA, PointB, (short) 0, ResultECPoint); 95 | } 96 | 97 | public static void ECPointAddition(ECPointBase PointA, byte[] PointB, short PointBOffset, ECPointBase ResultECPoint) { 98 | if (PointA != ResultECPoint) { 99 | PointA.getW(pt_A_arr, (short) 0); 100 | ResultECPoint.setW(pt_A_arr, (short) 0, (short) pt_A_arr.length); 101 | } 102 | ResultECPoint.AddPoint(PointB, PointBOffset, Consts.SHARE_DOUBLE_SIZE_CARRY); 103 | } 104 | 105 | void AddPoint(byte[] data, short dataOffset, short dataLen) { 106 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 107 | } 108 | 109 | 110 | 111 | // 112 | // ECKey methods 113 | // 114 | public void setFieldFP(byte[] bytes, short s, short s1) throws CryptoException { 115 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 116 | } 117 | 118 | public void setFieldF2M(short s) throws CryptoException { 119 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 120 | } 121 | 122 | public void setFieldF2M(short s, short s1, short s2) throws CryptoException { 123 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 124 | } 125 | 126 | public void setA(byte[] bytes, short s, short s1) throws CryptoException { 127 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 128 | } 129 | 130 | public void setB(byte[] bytes, short s, short s1) throws CryptoException { 131 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 132 | } 133 | 134 | public void setG(byte[] bytes, short s, short s1) throws CryptoException { 135 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 136 | } 137 | 138 | public void setR(byte[] bytes, short s, short s1) throws CryptoException { 139 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 140 | } 141 | 142 | public void setK(short s) { 143 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 144 | } 145 | 146 | public short getField(byte[] bytes, short s) throws CryptoException { 147 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 148 | return (short) -1; 149 | } 150 | 151 | public short getA(byte[] bytes, short s) throws CryptoException { 152 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 153 | return (short) -1; 154 | } 155 | 156 | public short getB(byte[] bytes, short s) throws CryptoException { 157 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 158 | return (short) -1; 159 | } 160 | 161 | public short getG(byte[] bytes, short s) throws CryptoException { 162 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 163 | return (short) -1; 164 | } 165 | 166 | public short getR(byte[] bytes, short s) throws CryptoException { 167 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 168 | return (short) -1; 169 | } 170 | 171 | public short getK() throws CryptoException { 172 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 173 | return (short) -1; 174 | } 175 | 176 | public void copyDomainParametersFrom(ECKey eckey) throws CryptoException { 177 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 178 | } 179 | 180 | } 181 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/ECPointBuilder.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.framework.ISOException; 4 | import mpc.jcmathlib.*; 5 | /** 6 | * 7 | * @author Petr Svenda 8 | */ 9 | public class ECPointBuilder { 10 | public static final byte ECPOINT_INSTANCE_TYPE_SW = (byte) 1; // JCMathLib 11 | public static final byte ECPOINT_INSTANCE_TYPE_NXP = (byte) 2; // NXP proprietary API 12 | public static final byte ECPOINT_INSTANCE_TYPE_GEMALTO = (byte) 3; // Gemalto proprietary API 13 | public static final byte ECPOINT_INSTANCE_TYPE_GD = (byte) 4; // G&D proprietary API 14 | public static final byte ECPOINT_INSTANCE_TYPE_FEITIAN = (byte) 5; // Fetian proprietary API 15 | 16 | public static final byte TYPE_EC_FP_POINT = (byte) 100; 17 | 18 | public static final byte ECPOINT_LIB = ECPOINT_INSTANCE_TYPE_SW; // Set proper library based on the underlying provider 19 | public static final byte ECPOINT_TYPE = TYPE_EC_FP_POINT; 20 | 21 | static ECCurve theCurve; 22 | static ECConfig ecc; 23 | 24 | static ECPointBase createPoint(short keyLen) { 25 | switch (ECPOINT_LIB) { 26 | case ECPOINT_INSTANCE_TYPE_SW: 27 | return ECPoint_SW.createPoint(ecc); 28 | case ECPOINT_INSTANCE_TYPE_NXP: 29 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 30 | break; 31 | case ECPOINT_INSTANCE_TYPE_GEMALTO: 32 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 33 | break; 34 | case ECPOINT_INSTANCE_TYPE_GD: 35 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 36 | break; 37 | case ECPOINT_INSTANCE_TYPE_FEITIAN: 38 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 39 | break; 40 | default: 41 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 42 | } 43 | return null; 44 | } 45 | 46 | public static void allocate(ECCurve curve, ECConfig ecCfg) { 47 | theCurve = curve; 48 | ecc = ecCfg; 49 | 50 | switch (ECPOINT_LIB) { 51 | case ECPOINT_INSTANCE_TYPE_SW: 52 | ECPoint_SW.allocate(ecc, theCurve); 53 | break; 54 | case ECPOINT_INSTANCE_TYPE_NXP: 55 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 56 | break; 57 | case ECPOINT_INSTANCE_TYPE_GEMALTO: 58 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 59 | break; 60 | case ECPOINT_INSTANCE_TYPE_GD: 61 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 62 | break; 63 | case ECPOINT_INSTANCE_TYPE_FEITIAN: 64 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 65 | break; 66 | default: 67 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/ECPoint_SW.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.framework.ISOException; 4 | import javacard.security.CryptoException; 5 | import javacard.security.KeyAgreement; 6 | import mpc.jcmathlib.*; 7 | /** 8 | * 9 | * @author Vasilios Mavroudis and Petr Svenda 10 | */ 11 | public class ECPoint_SW extends mpc.ECPointBase { 12 | public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN = (byte) 3; 13 | public static final byte KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY = (byte) 6; 14 | 15 | static ResourceManager rm; 16 | 17 | static ECPoint fnc_addPoint_other = null; 18 | static ECPoint fnc_ScalarMultiplication_basePoint = null; 19 | static ECPoint fnc_ScalarMultiplication_resultPoint = null; 20 | static ECPoint fnc_ScalarMultiplication_standardG = null; 21 | 22 | ECPoint m_swECPoint; 23 | 24 | private ECPoint_SW(ECPoint point) { 25 | m_swECPoint = point; 26 | } 27 | 28 | static ECPoint_SW createPoint(ECConfig ecc) { 29 | return new mpc.ECPoint_SW(new ECPoint(theCurve, ecc.ech)); 30 | } 31 | 32 | public static void allocate(ECConfig ecc, ECCurve curve) { 33 | rm = ecc.rm; 34 | theCurve = curve; 35 | if (fnc_addPoint_other == null) { 36 | fnc_addPoint_other = new ECPoint(theCurve, ecc.ech); 37 | //rm.locker.registerLock(fnc_addPoint_other); 38 | } 39 | if (fnc_ScalarMultiplication_basePoint == null) { 40 | fnc_ScalarMultiplication_basePoint = new ECPoint(theCurve, ecc.ech); 41 | fnc_ScalarMultiplication_resultPoint = fnc_ScalarMultiplication_basePoint; // reuse same point - BUGBUG: use proper ResourceManager for sharing 42 | //rm.locker.registerLock(fnc_ScalarMultiplication_basePoint); 43 | } 44 | 45 | if (fnc_ScalarMultiplication_standardG == null) { 46 | fnc_ScalarMultiplication_standardG = new ECPoint(theCurve, ecc.ech); 47 | } 48 | 49 | /* unused 50 | // TODO: JC 3.0.5 introduces KeyAgreement.ALG_EC_SVDP_DH_PLAIN_XY - but not yet supported on available cards 51 | ECMultiplHelper = KeyAgreement.getInstance(KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY, false); 52 | ECMultiplHelperDecrypt = KeyAgreement.getInstance(KeyAgreement_ALG_EC_SVDP_DH_PLAIN_XY, false); 53 | */ 54 | } 55 | 56 | public short ScalarMultiplication(byte[] BasePoint, short BasePointOffset, short BasePointLen, byte[] value, byte[] result) { 57 | //rm.locker.lock(fnc_ScalarMultiplication_basePoint); 58 | // in case BasePoint is different from G, then update of curve is necessary 59 | fnc_ScalarMultiplication_basePoint.getCurve().setG(BasePoint, BasePointOffset, BasePointLen); 60 | fnc_ScalarMultiplication_basePoint.updatePointObjects(); // After changing curve parameters, internal objects needs to be actualized 61 | 62 | fnc_ScalarMultiplication_basePoint.setW(BasePoint, BasePointOffset, BasePointLen); 63 | fnc_ScalarMultiplication_basePoint.multiplication(value, (short) 0, (short) value.length); 64 | 65 | short len = fnc_ScalarMultiplication_basePoint.getW(result, (short) 0); 66 | //rm.locker.unlock(fnc_ScalarMultiplication_basePoint); 67 | 68 | return len; 69 | } 70 | 71 | public short ScalarMultiplication(ECPointBase BasePoint, KeyAgreement ecKeyAgreement, byte[] result) { 72 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 73 | return -1; 74 | } 75 | 76 | public void ScalarMultiplication(ECPointBase BasePoint, KeyAgreement ecKeyAgreement, ECPointBase ResultECPoint) { 77 | ISOException.throwIt(Consts.SW_NOTSUPPORTEDYET); 78 | } 79 | 80 | public short ScalarMultiplication(byte[] BasePoint, short BasePointOffset, short BasePointLen, KeyAgreement ecKeyAgreement, byte[] result) { 81 | return -1; 82 | } 83 | 84 | public void ScalarMultiplication(ECPointBase BasePoint, byte[] value, ECPointBase ResultECPoint) { 85 | short len = ScalarMultiplication(BasePoint, value, TempBuffer65); 86 | ResultECPoint.setW(TempBuffer65, (short) 0, len); 87 | } 88 | 89 | public short ScalarMultiplication(ECPointBase BasePoint, byte[] value, byte[] result) { 90 | short len = BasePoint.getW(TempBuffer65, (short) 0); 91 | ///* in case BasePoint is different from G, then update of curve is necessary (not used in MPC) 92 | fnc_ScalarMultiplication_resultPoint.getCurve().setG(TempBuffer65, (short) 0, len); 93 | fnc_ScalarMultiplication_resultPoint.updatePointObjects(); // After changing curve parameters, internal objects needs to be actualized 94 | /**/ 95 | fnc_ScalarMultiplication_resultPoint.setW(TempBuffer65, (short) 0, len); 96 | fnc_ScalarMultiplication_resultPoint.multiplication(value, (short) 0, (short) value.length); 97 | len = fnc_ScalarMultiplication_resultPoint.getW(result, (short) 0); 98 | return len; 99 | } 100 | 101 | 102 | public void setW(byte[] g, short gOffset, short gLen) { 103 | m_swECPoint.setW(g, gOffset, gLen); 104 | } 105 | 106 | public short getW(byte[] g, short gOffset) { 107 | return m_swECPoint.getW(g, gOffset); 108 | } 109 | 110 | void AddPoint(byte[] data, short dataOffset, short dataLen) { 111 | //rm.locker.lock(fnc_addPoint_other); 112 | fnc_addPoint_other.setW(data, dataOffset, dataLen); 113 | m_swECPoint.add(fnc_addPoint_other); 114 | //rm.locker.unlock(fnc_addPoint_other); 115 | } 116 | 117 | // 118 | // ECKey methods 119 | // 120 | public void setFieldFP(byte[] bytes, short s, short s1) throws CryptoException { 121 | m_swECPoint.setFieldFP(bytes, s, s1); 122 | } 123 | 124 | public void setFieldF2M(short s) throws CryptoException { 125 | m_swECPoint.setFieldF2M(s); 126 | } 127 | 128 | public void setFieldF2M(short s, short s1, short s2) throws CryptoException { 129 | m_swECPoint.setFieldF2M(s, s1, s2); 130 | } 131 | 132 | public void setA(byte[] bytes, short s, short s1) throws CryptoException { 133 | m_swECPoint.setA(bytes, s, s1); 134 | } 135 | 136 | public void setB(byte[] bytes, short s, short s1) throws CryptoException { 137 | m_swECPoint.setB(bytes, s, s1); 138 | } 139 | 140 | public void setG(byte[] bytes, short s, short s1) throws CryptoException { 141 | m_swECPoint.setG(bytes, s, s1); 142 | } 143 | 144 | public void setR(byte[] bytes, short s, short s1) throws CryptoException { 145 | m_swECPoint.setR(bytes, s, s1); 146 | } 147 | 148 | public void setK(short s) { 149 | m_swECPoint.setK(s); 150 | } 151 | 152 | public short getField(byte[] bytes, short s) throws CryptoException { 153 | return m_swECPoint.getField(bytes, s); 154 | } 155 | 156 | public short getA(byte[] bytes, short s) throws CryptoException { 157 | return m_swECPoint.getA(bytes, s); 158 | } 159 | 160 | public short getB(byte[] bytes, short s) throws CryptoException { 161 | return m_swECPoint.getB(bytes, s); 162 | } 163 | 164 | public short getG(byte[] bytes, short s) throws CryptoException { 165 | return m_swECPoint.getG(bytes, s); 166 | } 167 | 168 | public short getR(byte[] bytes, short s) throws CryptoException { 169 | return m_swECPoint.getR(bytes, s); 170 | } 171 | 172 | public short getK() throws CryptoException { 173 | return m_swECPoint.getK(); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/MPCCryptoOps.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.security.MessageDigest; 4 | import javacard.framework.ISOException; 5 | import javacard.framework.JCSystem; 6 | import javacard.framework.Util; 7 | import javacard.security.RandomData; 8 | import mpc.jcmathlib.*; 9 | /** 10 | * 11 | * @author Vasilios Mavroudis and Petr Svenda 12 | */ 13 | public class MPCCryptoOps { 14 | RandomData randomData = null; 15 | MessageDigest md = null; 16 | 17 | Bignat temp_sign_counter = null; 18 | 19 | ECPointBase placeholder = null; 20 | ECPointBase c2_EC = null; 21 | ECPointBase GenPoint = null; 22 | ECPointBase plaintext_EC = null; 23 | ECPointBase tmp_EC = null; 24 | byte[] y_Bn = null; 25 | byte[] encResult = null; 26 | byte[] e_arr = null; 27 | byte[] tmp_k_n = null; 28 | byte[] prf_result = null; 29 | 30 | Bignat modulo_Bn = null; 31 | Bignat e_Bn = null; 32 | Bignat s_Bn = null; 33 | Bignat xe_Bn = null; 34 | Bignat xi_Bn = null; 35 | Bignat aBn = null; 36 | 37 | Bignat resBn1 = null; 38 | Bignat resBn2 = null; 39 | Bignat resBn3 = null; 40 | 41 | // AddPoint operations 42 | Bignat four_Bn = null; 43 | Bignat five_Bn = null; 44 | Bignat p_Bn = null; 45 | 46 | byte[] m_shortByteArray = null; // used to return short represenated as array of 2 bytes 47 | byte[] tmp_arr = null; // TODO: used as array for temporary result -> move to resource manager 48 | 49 | 50 | static final short SHIFT_BYTES_AAPROX = Consts.SHARE_DOUBLE_SIZE_CARRY; 51 | static short res2Len = (short) ((short) 97 - SHIFT_BYTES_AAPROX); 52 | 53 | //static byte[] citConst = {(byte) 0x01, (byte) 0x00, (byte) 0x01}; 54 | //static byte[] citConst = {(byte) 0x0, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xbc, (byte) 0xe6, (byte) 0xfa, (byte) 0xad, (byte) 0xa7, (byte) 0x17, (byte) 0x9e, (byte) 0x84, (byte) 0xf3, (byte) 0xb9, (byte) 0xca, (byte) 0xc2, (byte) 0xfc, (byte) 0x63, (byte) 0x25, (byte) 0x51}; 55 | static byte[] r_for_BigInteger = { 56 | (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xff, (byte) 0xff, (byte) 0xff, 57 | (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, 58 | (byte) 0xff, (byte) 0x43, (byte) 0x19, (byte) 0x05, (byte) 0x52, (byte) 0xdf, (byte) 0x1a, (byte) 0x6c, 59 | (byte) 0x21, (byte) 0x01, (byte) 0x2f, (byte) 0xfd, (byte) 0x85, (byte) 0xee, (byte) 0xdf, (byte) 0x9b, 60 | (byte) 0xfe, (byte) 0x67}; 61 | 62 | static byte[] aBn_pow_2 = { 63 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 64 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 65 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 66 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 67 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 68 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 69 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 70 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, 71 | (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, 72 | (byte) 0xFF, (byte) 0xFD, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFC, (byte) 0x86, (byte) 0x32, 73 | (byte) 0x0A, (byte) 0xA4, (byte) 0x44, (byte) 0x66, (byte) 0xE2, (byte) 0xE8, (byte) 0xC0, (byte) 0x94, 74 | (byte) 0xD3, (byte) 0x4F, (byte) 0x59, (byte) 0xED, (byte) 0x28, (byte) 0x63, (byte) 0x78, (byte) 0xEE, 75 | (byte) 0x70, (byte) 0x50, (byte) 0x78, (byte) 0x7E, (byte) 0xEB, (byte) 0xFF, (byte) 0x3C, (byte) 0x87, 76 | (byte) 0xC1, (byte) 0x57, (byte) 0x3A, (byte) 0x89, (byte) 0xD7, (byte) 0x29, (byte) 0x38, (byte) 0x99, 77 | (byte) 0xDB, (byte) 0x3F, (byte) 0x42, (byte) 0x81, (byte) 0x40, (byte) 0x09, (byte) 0xDF, (byte) 0xC9, 78 | (byte) 0x49, (byte) 0x4B, (byte) 0x31, (byte) 0xC9, (byte) 0x7F, (byte) 0x8A, (byte) 0x8D, (byte) 0x71}; 79 | 80 | static byte[] modulo_Bn_pow_2 = { 81 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 82 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 83 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 84 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 85 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 86 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 87 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 88 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 89 | (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, 90 | (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 91 | (byte) 0x79, (byte) 0xCD, (byte) 0xF5, (byte) 0x5B, (byte) 0xD4, (byte) 0x61, (byte) 0x47, (byte) 0xAE, 92 | (byte) 0x13, (byte) 0x12, (byte) 0x4D, (byte) 0xD7, (byte) 0x5F, (byte) 0x81, (byte) 0xF2, (byte) 0x26, 93 | (byte) 0x00, (byte) 0x43, (byte) 0x66, (byte) 0x1F, (byte) 0x1D, (byte) 0x81, (byte) 0x9D, (byte) 0x01, 94 | (byte) 0x9A, (byte) 0x02, (byte) 0xFC, (byte) 0xD8, (byte) 0x5D, (byte) 0x72, (byte) 0x4A, (byte) 0xA1, 95 | (byte) 0x32, (byte) 0xAD, (byte) 0x5E, (byte) 0x5D, (byte) 0xE4, (byte) 0x69, (byte) 0xC2, (byte) 0x7B, 96 | (byte) 0xAB, (byte) 0x0D, (byte) 0xBA, (byte) 0xA1, (byte) 0x5A, (byte) 0x16, (byte) 0x83, (byte) 0xA1}; 97 | 98 | public MPCCryptoOps(ECConfig eccfg) { 99 | temp_sign_counter = new Bignat((short) 2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 100 | tmp_arr = JCSystem.makeTransientByteArray(Consts.SHARE_DOUBLE_SIZE_CARRY, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 101 | 102 | placeholder = ECPointBuilder.createPoint(SecP256r1.KEY_LENGTH); 103 | placeholder.initializeECPoint_SecP256r1(); 104 | 105 | c2_EC = ECPointBuilder.createPoint(SecP256r1.KEY_LENGTH); 106 | c2_EC.initializeECPoint_SecP256r1(); 107 | 108 | GenPoint = ECPointBuilder.createPoint(SecP256r1.KEY_LENGTH); 109 | GenPoint.setW(SecP256r1.G, (short) 0, (short) SecP256r1.G.length); 110 | 111 | plaintext_EC = ECPointBuilder.createPoint(SecP256r1.KEY_LENGTH); 112 | plaintext_EC.initializeECPoint_SecP256r1(); 113 | 114 | tmp_EC = ECPointBuilder.createPoint(SecP256r1.KEY_LENGTH); 115 | tmp_EC.initializeECPoint_SecP256r1(); 116 | 117 | randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM); 118 | 119 | y_Bn = JCSystem.makeTransientByteArray(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 120 | 121 | encResult = JCSystem.makeTransientByteArray(Consts.SHARE_DOUBLE_SIZE_CARRY, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 122 | 123 | e_arr = JCSystem.makeTransientByteArray(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 124 | 125 | md = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false); 126 | 127 | tmp_k_n = JCSystem.makeTransientByteArray(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 128 | prf_result = JCSystem.makeTransientByteArray(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 129 | 130 | modulo_Bn = new Bignat(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 131 | modulo_Bn.from_byte_array((short) SecP256r1.r.length, (short) 0, SecP256r1.r, (short) 0); 132 | 133 | aBn = new Bignat(Consts.SHARE_DOUBLE_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 134 | 135 | aBn.set_from_byte_array((short) (aBn.length() - (short) r_for_BigInteger.length), r_for_BigInteger, (short) 0, (short) r_for_BigInteger.length); 136 | 137 | e_Bn = new Bignat(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 138 | s_Bn = new Bignat(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 139 | xi_Bn = new Bignat(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 140 | xe_Bn = new Bignat(Consts.SHARE_DOUBLE_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 141 | 142 | resBn1 = new Bignat((short) ((short) (eccfg.bnh.MULT_RSA_ENGINE_MAX_LENGTH_BITS / 8) + 1), JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 143 | resBn2 = new Bignat(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 144 | resBn3 = new Bignat(Consts.SHARE_DOUBLE_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 145 | 146 | // AddPoint objects 147 | four_Bn = new Bignat((short) 32, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 148 | five_Bn = new Bignat((short) 32, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 149 | p_Bn = new Bignat((short) 32, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 150 | 151 | md = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false); 152 | 153 | m_shortByteArray = JCSystem.makeTransientByteArray((short) 2, JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT); 154 | } 155 | /** 156 | * Encrypts provided plaintext data with aggregated public key (Algorithm 4.4). 157 | * For encryption, we use the Elliptic Curve ElGamal scheme. This operation does not use the secret key, and can be 158 | * performed directly on the host, or remotely by any party holding the public key, hence there is no need to perform 159 | * it in a distributed manner. 160 | * @param quorumCtx quorum context 161 | * @param plaintextArray input buffer with message encoded as an element of the group G 162 | * @param plaintextArrayOffset start offset within plaintext_arr 163 | * @param plaintextArrayOffsetLength length of data 164 | * @param outArray output array with encrypted data 165 | * @return length of output data 166 | */ 167 | public short Encrypt(QuorumContext quorumCtx, byte[] plaintextArray, short plaintextArrayOffset, short plaintextArrayOffsetLength, byte[] outArray) { 168 | 169 | short outOffset = (short) 0; 170 | 171 | // Check input data validity 172 | if (plaintextArrayOffsetLength != Consts.PUBKEY_YS_SHARE_SIZE) { 173 | ISOException.throwIt(Consts.SW_INVALIDMESSAGELENGTH); 174 | } 175 | // TODO: Check if message is element of the group 176 | 177 | PM.check(PM.TRAP_CRYPTOPS_ENCRYPT_1); 178 | 179 | // Generate random 180 | randomData.generateData(y_Bn, (short) 0, (short) y_Bn.length); //4ms 181 | 182 | PM.check(PM.TRAP_CRYPTOPS_ENCRYPT_2); 183 | 184 | // Optimization: Pre-initialize KeyAgreement - we will use it twice so set it only once and reuse // 60ms 185 | if (ECPointBase.ECMultiplHelper != null) { // Use prepared engine - cards with native support for EC 186 | ECPointBase.disposable_priv.setS(y_Bn, (short) 0, (short) y_Bn.length); 187 | ECPointBase.ECMultiplHelper.init(ECPointBase.disposable_priv); // Set multiplier 188 | } 189 | 190 | PM.check(PM.TRAP_CRYPTOPS_ENCRYPT_3); 191 | 192 | // Gen c2 first as we will reuse same output array 193 | // c2 = m + (xG) + (yG) = y(xG) + m = yPub + m 194 | if (ECPointBase.ECMultiplHelper != null) { 195 | // Use prepared engine - cards with native support for EC 196 | c2_EC.ScalarMultiplication(quorumCtx.GetY(), ECPointBase.ECMultiplHelper, c2_EC); // y(xG) //170ms 197 | } 198 | else { 199 | // Use this with JCMathLib 200 | c2_EC.ScalarMultiplication(quorumCtx.GetY(), y_Bn, c2_EC); // y(xG) 201 | } 202 | 203 | PM.check(PM.TRAP_CRYPTOPS_ENCRYPT_4); 204 | 205 | ECPointBase.ECPointAddition(c2_EC, plaintextArray, plaintextArrayOffset, c2_EC); // +m //150ms 206 | 207 | PM.check(PM.TRAP_CRYPTOPS_ENCRYPT_5); 208 | 209 | // Gen c1 now 210 | if (ECPointBase.ECMultiplHelper != null) { 211 | // Use prepared engine - cards with native support for EC 212 | outOffset += placeholder.ScalarMultiplication(GenPoint, ECPointBase.ECMultiplHelper, outArray); // yG // 129ms 213 | } 214 | else { 215 | // Use this with JCMathLib 216 | outOffset += placeholder.ScalarMultiplication(GenPoint, y_Bn, outArray); // yG 217 | } 218 | PM.check(PM.TRAP_CRYPTOPS_ENCRYPT_6); 219 | 220 | outOffset += c2_EC.getW(outArray, outOffset); // append c2_EC behind yG 221 | 222 | return outOffset; 223 | } 224 | 225 | /** 226 | * Decrypts provided ciphertext with participant's share (Algorithm 4.5). 227 | * @param quorumCtx quorum context 228 | * @param ciphertextArray input buffer with ciphertext 229 | * @param ciphertextArrayOffset start offset within ciphertext buffer 230 | * @param outputArray output array with decrypted share 231 | * @return length of decrypted share 232 | */ 233 | public short DecryptShare(QuorumContext quorumCtx, byte[] ciphertextArray, short ciphertextArrayOffset, byte[] outputArray) { 234 | 235 | PM.check(PM.TRAP_CRYPTOPS_DECRYPTSHARE_1); 236 | 237 | short len; 238 | if (ECPointBase.ECMultiplHelperDecrypt != null) { 239 | // Use prepared engine - cards with native support for EC. Already set from Reset method with quorumCtx.GetXi() 240 | len = placeholder.ScalarMultiplication(ciphertextArray, ciphertextArrayOffset, Consts.SHARE_DOUBLE_SIZE_CARRY, ECPointBase.ECMultiplHelperDecrypt, outputArray); // -xyG 241 | } else { 242 | // Use this with JCMathLib 243 | len = placeholder.ScalarMultiplication(ciphertextArray, ciphertextArrayOffset, Consts.SHARE_DOUBLE_SIZE_CARRY, quorumCtx.GetXi(), outputArray); // -xyG 244 | } 245 | 246 | PM.check(PM.TRAP_CRYPTOPS_DECRYPTSHARE_2); 247 | 248 | return len; 249 | } 250 | 251 | /** 252 | * The signing phase starts with the host sending a Sign request to all ICs (Algorithm 4.7). 253 | * Such a request includes the hash of the plaintext Hash(m), the index of 254 | * the round counter j, and the random group element R_n corresponding to the round. 255 | * Each IC then first verifies that the host has the authorization to submit 256 | * queries and that the specific counter j has not been already used. The latter 257 | * check on j is to prevent attacks that aim to either leak the private key 258 | * or to allow the adversary to craft new signatures from existing ones. If 259 | * these checks are successful, the IC executes Algorithm 4.7 and generates 260 | * its signature share. The signature share (σi, j , ϵj ) is then sent to 261 | * the host. 262 | * 263 | * @param quorumCtx current quorum context 264 | * @param counter strictly incremental counter 265 | * @param plaintextAndRnArray array with message and R_n 266 | * @param plaintextOffset start offset inside plaintext array 267 | * @param plaintextLength lengths of data inside plaintext array 268 | * @param outputArray 269 | * @param outputArrayOffset 270 | * @return 271 | */ 272 | public short Sign(QuorumContext quorumCtx, Bignat counter, byte[] plaintextAndRnArray, short plaintextOffset, short plaintextLength, byte[] outputArray, short outputArrayOffset) { 273 | 274 | PM.check(PM.TRAP_CRYPTOPS_SIGN_1); 275 | 276 | // Check counter - must not repeat 277 | if (!MPCApplet.bIsSimulator) { // Don't perform counter checks on simulator to enable for bogus test cases 278 | if (quorumCtx.signature_counter.lesser(counter) == false) { 279 | ISOException.throwIt(Consts.SW_INVALIDCOUNTER); 280 | } 281 | } 282 | 283 | if (plaintextLength != (short) (Consts.SHARE_DOUBLE_SIZE_CARRY + Consts.SHARE_DOUBLE_SIZE_CARRY)) { 284 | ISOException.throwIt(Consts.SW_INVALIDMESSAGELENGTH); 285 | } 286 | 287 | PM.check(PM.TRAP_CRYPTOPS_SIGN_2); //+8ms 288 | 289 | // 2. Compute e = H(M||R_n) 290 | md.reset(); 291 | md.update(plaintextAndRnArray, plaintextOffset, Consts.SHARE_DOUBLE_SIZE_CARRY); // hash plaintext 292 | md.doFinal(plaintextAndRnArray, (short) (plaintextOffset + Consts.SHARE_DOUBLE_SIZE_CARRY), Consts.SHARE_DOUBLE_SIZE_CARRY, e_arr, (short) 0); //Hash R_n 293 | e_Bn.from_byte_array(Consts.SHARE_BASIC_SIZE, (short) 0, e_arr, (short) 0); 294 | 295 | 296 | PM.check(PM.TRAP_CRYPTOPS_SIGN_3); // +15ms 297 | // s 298 | //s_Bn.zero(); 299 | s_Bn.from_byte_array(Consts.SHARE_BASIC_SIZE, (short) 0, PRF(counter, quorumCtx.signature_secret_seed), (short) 0); // s 300 | 301 | 302 | PM.check(PM.TRAP_CRYPTOPS_SIGN_4); 303 | // xe 304 | //xe_Bn.zero(); 305 | xe_Bn.resize_to_max(true); // xe_Bn is shrinked below => resize long-term object back to initial maximum size 306 | 307 | PM.check(PM.TRAP_CRYPTOPS_SIGN_5); 308 | //xi_Bn.zero(); 309 | xi_Bn.from_byte_array(Consts.SHARE_BASIC_SIZE, (short) 0, quorumCtx.GetXi(), (short) 0); 310 | //xe_Bn.mult(xi_Bn, e_Bn); // 330ms 311 | xe_Bn.mult_RSATrick(xi_Bn, e_Bn); // 90ms 312 | //test_multRSATrick(xi_Bn, e_Bn, null, xe_Bn); 313 | 314 | PM.check(PM.TRAP_CRYPTOPS_SIGN_6); 315 | 316 | // 317 | // Compute xe_Bn mod modulo_Bn 318 | // 319 | // xe_Bn.remainder_divide(modulo_Bn, null); // original working (but slow) command // 470ms 320 | // Speedup: xe_Bn % aBn = xe_Bn - ((xe_Bn * aBn) >> k) * aBn 321 | // (xe_Bn * aBn) 322 | resBn1.mult_rsa_trick(aBn, xe_Bn, aBn_pow_2, null); // as aBn is fixed, aBn^2 can be precomputed 323 | // ((n * a) >> k) 324 | // ((n * a) >> k) * r 325 | resBn2.set_from_byte_array((short) 0, resBn1.as_byte_array(), (short) ((short) (resBn1.length() - SHIFT_BYTES_AAPROX) - resBn2.length()), resBn2.length()); 326 | resBn3.mult_rsa_trick(modulo_Bn, resBn2, modulo_Bn_pow_2, null); // as modulo_Bn is fixed, modulo_Bn^2 can be precomputed 327 | 328 | // n - ((n * a) >> k) * r 329 | byte[] result = xe_Bn.as_byte_array(); 330 | byte[] inter = resBn3.as_byte_array(); 331 | Bignat.subtract(result, (short) 0, (short) result.length, inter, (short) 0, (short) inter.length); 332 | 333 | PM.check(PM.TRAP_CRYPTOPS_SIGN_7); 334 | xe_Bn.shrink(); // Resize back to 32 Bytes 335 | 336 | PM.check(PM.TRAP_CRYPTOPS_SIGN_8); 337 | 338 | if (s_Bn.lesser(xe_Bn)) { // remember s holds only k at this point 339 | s_Bn.add(modulo_Bn); 340 | } 341 | else { 342 | // bogus branch to prevent direct leak if s_Bn.lesser(xe_Bn) info in timing channel 343 | resBn2.add(modulo_Bn); 344 | } 345 | 346 | PM.check(PM.TRAP_CRYPTOPS_SIGN_9); 347 | 348 | // s = k -xe 349 | s_Bn.times_minus(xe_Bn, (short) 0, (short) 1); // k-xe 350 | 351 | PM.check(PM.TRAP_CRYPTOPS_SIGN_10); 352 | 353 | quorumCtx.signature_counter.copy(counter); 354 | 355 | // Return result 356 | short outOffset = outputArrayOffset; 357 | Util.arrayCopyNonAtomic(s_Bn.as_byte_array(), (short) 0, outputArray, outOffset, (short) s_Bn.as_byte_array().length); 358 | outOffset += (short) s_Bn.as_byte_array().length; 359 | Util.arrayCopyNonAtomic(e_Bn.as_byte_array(), (short) 0, outputArray, (short) s_Bn.as_byte_array().length, (short) e_Bn.as_byte_array().length); 360 | outOffset += (short) e_Bn.as_byte_array().length; 361 | return (short) (outOffset - outputArrayOffset); 362 | } 363 | 364 | public byte[] PRF(short i, byte[] secret_arr) { 365 | return PRF(shortToByteArray(i), secret_arr); 366 | } 367 | 368 | public byte[] PRF(Bignat i, byte[] secret_arr) { 369 | return PRF(i.as_byte_array(), secret_arr); 370 | } 371 | 372 | public byte[] PRF(byte[] counter, byte[] secret_arr) { 373 | md.reset(); 374 | md.update(counter, (short) 0, (short) counter.length); 375 | md.doFinal(secret_arr, (short) 0, (short) secret_arr.length, prf_result, (short) 0); 376 | return prf_result; 377 | } 378 | 379 | public byte[] shortToByteArray(short s) { 380 | Util.setShort(m_shortByteArray, (short) 0, s); 381 | return m_shortByteArray; 382 | } 383 | 384 | public boolean VerifyYsCommitment(byte[] Ys, short YsOffset, short YsLength, byte[] commitment) { 385 | if (YsLength != Consts.PUBKEY_YS_SHARE_SIZE) { 386 | ISOException.throwIt(Consts.SW_INVALIDYSHARE); 387 | } 388 | md.reset(); 389 | md.doFinal(Ys, YsOffset, YsLength, tmp_arr, (short) 0); 390 | return Util.arrayCompare(tmp_arr, (short) 0, commitment, (short) 0, Consts.SHARE_BASIC_SIZE) == 0; 391 | } 392 | 393 | /** 394 | * Part of novel multi-signature scheme, based on Schnorr signature (Algorithm 4.7). Host queries the 395 | * ICs for random group elements Rij, where i is the id of the IC and j an 396 | * increasing request counter. Once such a request is 397 | * received, the IC verifies that the host is authorized to submit such a 398 | * request and then applies the keyed pseudorandom function on the index j 399 | * to compute ri, j = PRFs (j). The IC then uses ri, j to generate a group 400 | * element (EC Point) Ri j = ri, j · G, which is then returned to the host. 401 | * @param counter strictly incremental counter (j) 402 | * @param cardSecretArray card's secret signature seed (ri) 403 | * @param outputArray buffer for signed share 404 | * @return length of signed share 405 | */ 406 | public short Gen_R_i(byte[] counter, byte[] cardSecretArray, byte[] outputArray) { 407 | return placeholder.ScalarMultiplication(GenPoint, PRF(counter, cardSecretArray), outputArray); // yG 408 | } 409 | } 410 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/PM.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.framework.ISOException; 4 | 5 | /** 6 | * Utility class for performance profiling. Contains definition of performance trap 7 | * constants and trap reaction method. 8 | * @author Petr Svenda 9 | */ 10 | public class PM { 11 | public static short m_perfStop = -1; // Performace measurement stop indicator 12 | 13 | // Performance-related debugging response codes 14 | public static final short PERF_START = (short) 0x0001; 15 | 16 | public static final short TRAP_UNDEFINED = (short) 0xffff; 17 | 18 | public static final short TRAP_CRYPTOPS_ENCRYPT = (short) 0x7580; 19 | public static final short TRAP_CRYPTOPS_ENCRYPT_1 = (short) (TRAP_CRYPTOPS_ENCRYPT + 1); 20 | public static final short TRAP_CRYPTOPS_ENCRYPT_2 = (short) (TRAP_CRYPTOPS_ENCRYPT + 2); 21 | public static final short TRAP_CRYPTOPS_ENCRYPT_3 = (short) (TRAP_CRYPTOPS_ENCRYPT + 3); 22 | public static final short TRAP_CRYPTOPS_ENCRYPT_4 = (short) (TRAP_CRYPTOPS_ENCRYPT + 4); 23 | public static final short TRAP_CRYPTOPS_ENCRYPT_5 = (short) (TRAP_CRYPTOPS_ENCRYPT + 5); 24 | public static final short TRAP_CRYPTOPS_ENCRYPT_6 = (short) (TRAP_CRYPTOPS_ENCRYPT + 6); 25 | public static final short TRAP_CRYPTOPS_ENCRYPT_COMPLETE = TRAP_CRYPTOPS_ENCRYPT_6; 26 | 27 | public static final short TRAP_CRYPTOPS_DECRYPTSHARE = (short) 0x7570; 28 | public static final short TRAP_CRYPTOPS_DECRYPTSHARE_1 = (short) (TRAP_CRYPTOPS_DECRYPTSHARE + 1); 29 | public static final short TRAP_CRYPTOPS_DECRYPTSHARE_2 = (short) (TRAP_CRYPTOPS_DECRYPTSHARE + 2); 30 | public static final short TRAP_CRYPTOPS_DECRYPTSHARE_COMPLETE = TRAP_CRYPTOPS_DECRYPTSHARE_2; 31 | 32 | public static final short TRAP_CRYPTOPS_SIGN = (short) 0x7560; 33 | public static final short TRAP_CRYPTOPS_SIGN_1 = (short) (TRAP_CRYPTOPS_SIGN + 1); 34 | public static final short TRAP_CRYPTOPS_SIGN_2 = (short) (TRAP_CRYPTOPS_SIGN + 2); 35 | public static final short TRAP_CRYPTOPS_SIGN_3 = (short) (TRAP_CRYPTOPS_SIGN + 3); 36 | public static final short TRAP_CRYPTOPS_SIGN_4 = (short) (TRAP_CRYPTOPS_SIGN + 4); 37 | public static final short TRAP_CRYPTOPS_SIGN_5 = (short) (TRAP_CRYPTOPS_SIGN + 5); 38 | public static final short TRAP_CRYPTOPS_SIGN_6 = (short) (TRAP_CRYPTOPS_SIGN + 6); 39 | public static final short TRAP_CRYPTOPS_SIGN_7 = (short) (TRAP_CRYPTOPS_SIGN + 7); 40 | public static final short TRAP_CRYPTOPS_SIGN_8 = (short) (TRAP_CRYPTOPS_SIGN + 8); 41 | public static final short TRAP_CRYPTOPS_SIGN_9 = (short) (TRAP_CRYPTOPS_SIGN + 9); 42 | public static final short TRAP_CRYPTOPS_SIGN_10 = (short) (TRAP_CRYPTOPS_SIGN + 10); 43 | public static final short TRAP_CRYPTOPS_SIGN_COMPLETE = TRAP_CRYPTOPS_SIGN_10; 44 | 45 | 46 | public static void check(short stopCondition) { 47 | if (PM.m_perfStop == stopCondition) { 48 | ISOException.throwIt(stopCondition); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/QuorumContext.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.framework.APDU; 4 | import javacard.framework.ISOException; 5 | import javacard.framework.JCSystem; 6 | import javacard.framework.Util; 7 | import javacard.security.ECPrivateKey; 8 | import javacard.security.ECPublicKey; 9 | import javacard.security.KeyPair; 10 | import mpc.jcmathlib.*; 11 | /** 12 | * 13 | * @author Vasilios Mavroudis and Petr Svenda 14 | */ 15 | public class QuorumContext { 16 | private MPCCryptoOps cryptoOps = null; 17 | 18 | public short CARD_INDEX_THIS = 0; // index of player realised by this card 19 | public short NUM_PLAYERS = 0; // current number of players 20 | 21 | class Player { 22 | public boolean bYsValid = false; // Is player's share (Ys) currently valid? 23 | public byte[] YsCommitment = null; // Value of comitment of player's share (hash(Ys)) 24 | public boolean bYsCommitmentValid = false; // Is comitment currently valid? 25 | } 26 | private Player[] players = null; // contexts for all protocol participants (including this card) 27 | 28 | // Signing 29 | public Bignat signature_counter = null; 30 | public short signature_counter_short = 0; 31 | public byte[] signature_secret_seed = null; 32 | 33 | // Distributed keypair generation share 34 | ECCurve theCurve = null; 35 | private KeyPair pair = null; 36 | private byte[] x_i_Bn = null; // share xi, which is a randomly sampled element from Zn 37 | private byte[] this_card_Ys = null; // Ys for this card (not stored in Player[] context as shares are combined on the fly) 38 | private mpc.ECPointBase Y_EC_onTheFly = null; // aggregated Ys computed on the fly instead of in one shot once all shares are provided (COMPUTE_Y_ONTHEFLY) 39 | private short Y_EC_onTheFly_shares_count = 0; // number of public key shares already provided and combined during KeyGen_StorePublicKey 40 | private short num_commitments_count = 0; // number of stored commitments 41 | 42 | private StateModel state = null; // current state of the protocol run - some operations are not available in given state 43 | 44 | 45 | public QuorumContext(ECConfig eccfg, ECCurve curve, MPCCryptoOps cryptoOperations) { 46 | cryptoOps = cryptoOperations; 47 | signature_counter = new Bignat(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET, eccfg.bnh); 48 | signature_secret_seed = new byte[Consts.SECRET_SEED_SIZE]; 49 | 50 | theCurve = curve; 51 | this.pair = theCurve.newKeyPair(this.pair); 52 | x_i_Bn = JCSystem.makeTransientByteArray(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 53 | 54 | players = new Player[Consts.MAX_NUM_PLAYERS]; 55 | this_card_Ys = JCSystem.makeTransientByteArray(Consts.PUBKEY_YS_SHARE_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 56 | for (short i = 0; i < Consts.MAX_NUM_PLAYERS; i++) { 57 | players[i] = new Player(); 58 | if (Consts.PLAYERS_IN_RAM) { 59 | players[i].YsCommitment = JCSystem.makeTransientByteArray(Consts.SHARE_BASIC_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); 60 | } else { 61 | players[i].YsCommitment = new byte[Consts.SHARE_BASIC_SIZE]; 62 | } 63 | } 64 | 65 | Y_EC_onTheFly = ECPointBuilder.createPoint(SecP256r1.KEY_LENGTH); 66 | Y_EC_onTheFly.initializeECPoint_SecP256r1(); 67 | 68 | state = new StateModel(); 69 | state.MakeStateTransition(StateModel.STATE_QUORUM_CLEARED); 70 | } 71 | 72 | public void SetupNew(short numPlayers, short thisPlayerIndex) { 73 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_SetupNew); 74 | // Reset previous state 75 | Reset(); 76 | 77 | if (numPlayers > Consts.MAX_NUM_PLAYERS || numPlayers < 1) { 78 | ISOException.throwIt(Consts.SW_TOOMANYPLAYERS); 79 | } 80 | if (thisPlayerIndex >= Consts.MAX_NUM_PLAYERS || thisPlayerIndex < 0) { 81 | ISOException.throwIt(Consts.SW_INVALIDPLAYERINDEX); 82 | } 83 | 84 | // Setup new state 85 | this.NUM_PLAYERS = numPlayers; 86 | this.CARD_INDEX_THIS = thisPlayerIndex; 87 | 88 | cryptoOps.randomData.generateData(signature_secret_seed, (short) 0, Consts.SHARE_BASIC_SIZE); // Utilized later during signature protocol in Sign() and Gen_R_i() 89 | if (Consts.IS_BACKDOORED_EXAMPLE) { 90 | Util.arrayFillNonAtomic(signature_secret_seed, (short) 0, Consts.SHARE_BASIC_SIZE, (byte) 0x33); 91 | } 92 | 93 | // TODO: store and setup user authorization keys (if provided) 94 | 95 | // Set state 96 | state.MakeStateTransition(StateModel.STATE_QUORUM_INITIALIZED); 97 | state.MakeStateTransition(StateModel.STATE_KEYGEN_CLEARED); 98 | } 99 | 100 | public void Reset() { 101 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_Reset); 102 | Invalidate(true); 103 | // Restore proper value of modulo_Bn (was possibly erased during the card's reset) 104 | cryptoOps.modulo_Bn.from_byte_array((short) SecP256r1.r.length, (short) 0, SecP256r1.r, (short) 0); 105 | cryptoOps.aBn.set_from_byte_array((short) (cryptoOps.aBn.length() - (short) MPCCryptoOps.r_for_BigInteger.length), MPCCryptoOps.r_for_BigInteger, (short) 0, (short) MPCCryptoOps.r_for_BigInteger.length); 106 | state.MakeStateTransition(StateModel.STATE_QUORUM_CLEARED); 107 | } 108 | 109 | short GetState() { 110 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_GetState); 111 | return state.GetState(); 112 | } 113 | 114 | /** 115 | * Initialize new quorum context and generates initial keypair for this card (Algorithm 4.1). 116 | * Sets quorum size (numPlayers), id of this card. Prepares necessary initial structures. 117 | * @param numPlayers number of participants in this quorum 118 | * @param cardID participant index assigned to this card 119 | * @param bPrepareDecryption if true, speedup engines for fast decryption are pre-prepared 120 | */ 121 | public void InitAndGenerateKeyPair(boolean bPrepareDecryption) { 122 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_InitAndGenerateKeyPair); 123 | 124 | // Invalidate previously generated keypair 125 | Invalidate(false); 126 | 127 | state.MakeStateTransition(StateModel.STATE_QUORUM_INITIALIZED); 128 | state.MakeStateTransition(StateModel.STATE_KEYGEN_CLEARED); 129 | 130 | pair.genKeyPair(); 131 | 132 | if (Consts.IS_BACKDOORED_EXAMPLE) { 133 | // This branch demonstrates behavior of malicious attacker 134 | GenerateExampleBackdooredKeyPair(); 135 | } else { 136 | // Legitimate generation of key as per protocol by non-compromised participants 137 | ((ECPrivateKey) pair.getPrivate()).getS(x_i_Bn, (short) 0); // Algorithm 4.1, step 1. 138 | } 139 | 140 | // Add this card share into (future) aggregate key 141 | cryptoOps.placeholder.ScalarMultiplication(cryptoOps.GenPoint, x_i_Bn, this_card_Ys); // yG Algorithm 4.1, step 2. 142 | Y_EC_onTheFly.setW(this_card_Ys, (short) 0, (short) this_card_Ys.length); 143 | Y_EC_onTheFly_shares_count++; // share for this card is included 144 | num_commitments_count = 1; // share for this card is included 145 | // Update stored x_i properties 146 | players[CARD_INDEX_THIS].bYsValid = true; 147 | // Compute commitment, Algorithm 4.1, step 3. 148 | cryptoOps.md.reset(); 149 | cryptoOps.md.doFinal(this_card_Ys, (short) 0, (short) this_card_Ys.length, players[CARD_INDEX_THIS].YsCommitment, (short) 0); 150 | players[CARD_INDEX_THIS].bYsCommitmentValid = true; 151 | 152 | // Pre-prepare engine for faster Decrypt later 153 | if (bPrepareDecryption) { 154 | if (ECPointBase.ECMultiplHelperDecrypt != null) { // Use prepared engine - cards with native support for EC 155 | ECPointBase.disposable_privDecrypt.setS(x_i_Bn, (short) 0, (short) x_i_Bn.length); 156 | ECPointBase.ECMultiplHelperDecrypt.init(ECPointBase.disposable_privDecrypt); 157 | } 158 | } 159 | state.MakeStateTransition(StateModel.STATE_KEYGEN_PRIVATEGENERATED); 160 | 161 | // In extreme case, quorum is of size 1 and final key is generated 162 | if (Y_EC_onTheFly_shares_count == NUM_PLAYERS) { 163 | state.MakeStateTransition(StateModel.STATE_KEYGEN_KEYPAIRGENERATED); 164 | } 165 | } 166 | 167 | public final byte[] privbytes_backdoored = {(byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55, (byte) 0x55}; 168 | /** 169 | * Generates intentionally insecure private key to demonstrate behaviour when 170 | * some participants are malicious. Private key bytes are all 0x55 ... 0x55 171 | */ 172 | void GenerateExampleBackdooredKeyPair() { 173 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_GenerateExampleBackdooredKeyPair); 174 | // If enabled, key is not generated randomly as required per protocol, but fixed to vulnerable value instead 175 | ECPublicKey pub = (ECPublicKey) pair.getPublic(); 176 | ECPrivateKey priv = (ECPrivateKey) pair.getPrivate(); 177 | 178 | // Set "backdoored" (known) private key - all 0x55 ... 0x55 179 | priv.setS(privbytes_backdoored, (short) 0, (short) privbytes_backdoored.length); 180 | ((ECPrivateKey) pair.getPrivate()).getS(x_i_Bn, (short) 0); 181 | // Compute and set corresponding public key (to backdoored private one) 182 | cryptoOps.placeholder.ScalarMultiplication(cryptoOps.GenPoint, privbytes_backdoored, cryptoOps.tmp_arr); 183 | pub.setW(cryptoOps.tmp_arr, (short) 0, (short) 65); 184 | } 185 | 186 | public short RetrieveCommitment(byte[] array, short offset) { 187 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_RetrieveCommitment); 188 | if (players[CARD_INDEX_THIS].bYsCommitmentValid) { 189 | Util.arrayCopyNonAtomic(players[CARD_INDEX_THIS].YsCommitment, (short) 0, array, offset, (short) players[CARD_INDEX_THIS].YsCommitment.length); 190 | return (short) players[CARD_INDEX_THIS].YsCommitment.length; 191 | } else { 192 | ISOException.throwIt(Consts.SW_INVALIDCOMMITMENT); 193 | return (short) -1; 194 | } 195 | } 196 | 197 | // State 0 198 | public void StoreCommitment(short id, byte[] commitment, short commitmentOffset, short commitmentLength) { 199 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_StoreCommitment); 200 | 201 | if (id < 0 || id == CARD_INDEX_THIS || id >= NUM_PLAYERS) { 202 | ISOException.throwIt(Consts.SW_INVALIDPLAYERINDEX); 203 | } 204 | if (commitmentLength != players[id].YsCommitment.length) { 205 | ISOException.throwIt(Consts.SW_INVALIDCOMMITMENTLENGTH); 206 | } 207 | if (players[id].bYsCommitmentValid) { 208 | // commitment already stored 209 | ISOException.throwIt(Consts.SW_COMMITMENTALREADYSTORED); 210 | } 211 | else { 212 | Util.arrayCopyNonAtomic(commitment, commitmentOffset, players[id].YsCommitment, (short) 0, commitmentLength); 213 | players[id].bYsCommitmentValid = true; 214 | num_commitments_count++; 215 | 216 | if (num_commitments_count == NUM_PLAYERS) { 217 | // All commitments were collected, allow for export of this card share 218 | state.MakeStateTransition(StateModel.STATE_KEYGEN_COMMITMENTSCOLLECTED); 219 | } 220 | 221 | } 222 | } 223 | 224 | /** 225 | * Sets public key share of other participant after verification of commitment match. 226 | * @param id index of target participant 227 | * @param Y buffer with target participant share 228 | * @param YOffset start offset within Y 229 | * @param YLength length of share 230 | */ 231 | public void SetYs(short id, byte[] Y, short YOffset, short YLength) { 232 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_SetYs); 233 | 234 | if (id < 0 || id == CARD_INDEX_THIS || id >= NUM_PLAYERS) { 235 | ISOException.throwIt(Consts.SW_INVALIDPLAYERINDEX); 236 | } 237 | if (players[id].bYsValid) { 238 | ISOException.throwIt(Consts.SW_SHAREALREADYSTORED); 239 | } 240 | if (id == CARD_INDEX_THIS) { 241 | ISOException.throwIt(Consts.SW_INVALIDPLAYERINDEX); 242 | } 243 | // Verify against previously stored hash 244 | // TODO: if commitment check fails, terminate protocol and reset to intial state (and return error) 245 | if (!players[id].bYsCommitmentValid) { 246 | ISOException.throwIt(Consts.SW_INVALIDCOMMITMENT); 247 | } 248 | if (!cryptoOps.VerifyYsCommitment(Y, YOffset, YLength, players[id].YsCommitment)) { 249 | ISOException.throwIt(Consts.SW_INVALIDCOMMITMENT); 250 | } 251 | 252 | // Directly add into Y_EC_onTheFly, no storage into RAM 253 | ECPointBase.ECPointAddition(Y_EC_onTheFly, Y, YOffset, Y_EC_onTheFly); 254 | players[id].bYsValid = true; 255 | Y_EC_onTheFly_shares_count++; 256 | 257 | // check if shares for all players were included. If yes, change the state 258 | if (Y_EC_onTheFly_shares_count == NUM_PLAYERS) { 259 | for (short i = 0; i < NUM_PLAYERS; i++) { 260 | if (!players[i].bYsValid) { 261 | ISOException.throwIt(Consts.SW_INTERNALSTATEMISMATCH); 262 | } 263 | } 264 | state.MakeStateTransition(StateModel.STATE_KEYGEN_SHARESCOLLECTED); 265 | 266 | // The combination of shares is performed on the fly directly into Y_EC_onTheFly 267 | // If all contributed, Y_EC_onTheFly holds resulting combined public key 268 | state.MakeStateTransition(StateModel.STATE_KEYGEN_KEYPAIRGENERATED); 269 | } 270 | } 271 | 272 | /** 273 | * Returns this card public key share 274 | * @param commitmentBuffer output buffer where to store commitment 275 | * @param commitmentOffset start offset within target output buffer 276 | * @return 277 | */ 278 | public short GetYi(byte[] commitmentBuffer, short commitmentOffset) { 279 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_GetYi); 280 | 281 | if (state.GetState() == StateModel.STATE_KEYGEN_COMMITMENTSCOLLECTED) { 282 | if (players[CARD_INDEX_THIS].bYsValid) { 283 | Util.arrayCopyNonAtomic(this_card_Ys, (short) 0, commitmentBuffer, commitmentOffset, (short) this_card_Ys.length); 284 | return (short) this_card_Ys.length; 285 | } else { 286 | ISOException.throwIt(Consts.SW_INVALIDYSHARE); 287 | } 288 | } else { 289 | ISOException.throwIt(Consts.SW_INCORRECTSTATE); 290 | } 291 | return 0; 292 | } 293 | 294 | // State STATE_KEYGEN_KEYPAIRGENERATED 295 | public byte[] GetXi() { // Used to sign and decrypt 296 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_GetXi); 297 | 298 | return x_i_Bn; 299 | } 300 | 301 | public short GetXi(byte[] array, short offset) { 302 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_GetXi); 303 | 304 | Util.arrayCopyNonAtomic(x_i_Bn, (short) 0, array, offset, (short) x_i_Bn.length); 305 | return (short) x_i_Bn.length; 306 | } 307 | 308 | // State STATE_KEYGEN_KEYPAIRGENERATED 309 | public ECPointBase GetY() { 310 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_GetY); 311 | return Y_EC_onTheFly; 312 | } 313 | 314 | public void Invalidate(boolean bEraseAllArrays) { 315 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_Invalidate); 316 | 317 | if (bEraseAllArrays) { 318 | cryptoOps.randomData.generateData(cryptoOps.tmp_arr, (short) 0, (short) cryptoOps.tmp_arr.length); 319 | cryptoOps.randomData.generateData(x_i_Bn, (short) 0, (short) x_i_Bn.length); 320 | cryptoOps.randomData.generateData(signature_secret_seed, (short) 0, (short) signature_secret_seed.length); 321 | cryptoOps.randomData.generateData(this_card_Ys, (short) 0, (short) this_card_Ys.length); 322 | 323 | } 324 | // Invalidate all items 325 | for (short i = 0; i < Consts.MAX_NUM_PLAYERS; i++) { 326 | players[i].bYsCommitmentValid = false; 327 | players[i].bYsValid = false; 328 | if (bEraseAllArrays) { 329 | cryptoOps.randomData.generateData(players[i].YsCommitment, (short) 0, (short) players[i].YsCommitment.length); 330 | } 331 | } 332 | 333 | // TODO: clear Y_EC_onTheFly 334 | 335 | 336 | Y_EC_onTheFly_shares_count = 0; 337 | num_commitments_count = 0; 338 | signature_counter.zero(); 339 | signature_counter_short = 0; 340 | 341 | state.MakeStateTransition(StateModel.STATE_QUORUM_CLEARED); 342 | } 343 | 344 | 345 | public short Encrypt(byte[] plaintext_arr, short plaintext_arr_offset, short plaintext_arr_len, byte[] outArray) { 346 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_Encrypt); 347 | return cryptoOps.Encrypt(this, plaintext_arr, plaintext_arr_offset, plaintext_arr_len, outArray); 348 | } 349 | 350 | public short DecryptShare(byte[] c1_c2_arr, short c1_c2_arr_offset, short c1_c2_arr_len, byte[] outputArray) { 351 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_DecryptShare); 352 | return cryptoOps.DecryptShare(this, c1_c2_arr, c1_c2_arr_offset, outputArray); 353 | } 354 | 355 | public short Sign_RetrieveRandomRi(short counter, byte[] buffer) { 356 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_Sign_RetrieveRandomRi); 357 | // Counter must be strictly increasing, check 358 | if (counter <= signature_counter_short) { 359 | ISOException.throwIt(Consts.SW_INVALIDCOUNTER); 360 | } 361 | signature_counter_short = counter; 362 | return cryptoOps.Gen_R_i(cryptoOps.shortToByteArray(signature_counter_short), signature_secret_seed, buffer); 363 | } 364 | 365 | public short Sign(Bignat counter, byte[] Rn_plaintext_arr, short plaintextOffset, short plaintextLength, byte[] outputArray, short outputBaseOffset) { 366 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_Sign); 367 | return cryptoOps.Sign(this, counter, Rn_plaintext_arr, plaintextOffset, plaintextLength, outputArray, outputBaseOffset); 368 | } 369 | 370 | public short Sign_GetCurrentCounter(byte[] outputArray, short outputBaseOffset) { 371 | state.CheckAllowedFunction(StateModel.FNC_QuorumContext_Sign_GetCurrentCounter); 372 | return signature_counter.copy_to_buffer(outputArray, outputBaseOffset); 373 | } 374 | 375 | 376 | /** 377 | * Verify if caller is authorized to submit request for given operation 378 | * Right now, no check is performed and request is always allowed 379 | * @param apdu 380 | */ 381 | public void VerifyCallerAuthorization(APDU apdu, short requestedFnc) { 382 | //state.CheckAllowedFunction(StateModel.FNC_QuorumContext_VerifyCallerAuthorization); 383 | // TODO: enable verification if required 384 | } 385 | } 386 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/ReturnCodes.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | /** 4 | * 5 | * @author Vasilios Mavroudis and Petr Svenda 6 | */ 7 | public class ReturnCodes { 8 | // Custom error response codes 9 | public static final short SW_BIGNAT_RESIZETOLONGER = (short) 0x7000; 10 | public static final short SW_BIGNAT_REALLOCATIONNOTALLOWED = (short) 0x7001; 11 | public static final short SW_BIGNAT_MODULOTOOLARGE = (short) 0x7002; 12 | public static final short SW_BIGNAT_INVALIDCOPYOTHER = (short) 0x7003; 13 | public static final short SW_BIGNAT_INVALIDRESIZE = (short) 0x7004; 14 | public static final short SW_LOCK_ALREADYLOCKED = (short) 0x7005; 15 | public static final short SW_LOCK_NOTLOCKED = (short) 0x7006; 16 | public static final short SW_LOCK_OBJECT_NOT_FOUND = (short) 0x7007; 17 | public static final short SW_LOCK_NOFREESLOT = (short) 0x7008; 18 | public static final short SW_LOCK_OBJECT_MISMATCH = (short) 0x7009; 19 | public static final short SW_ECPOINT_INVALIDLENGTH = (short) 0x700a; 20 | public static final short SW_ECPOINT_UNEXPECTED_KA_LEN = (short) 0x700b; 21 | public static final short SW_ALLOCATOR_INVALIDOBJID = (short) 0x700c; 22 | 23 | 24 | // Specific codes to propagate exceptions cought 25 | // lower byte of exception is value as defined in JCSDK/api_classic/constant-values.htm 26 | public final static short SW_Exception = (short) 0xff01; 27 | public final static short SW_ArrayIndexOutOfBoundsException = (short) 0xff02; 28 | public final static short SW_ArithmeticException = (short) 0xff03; 29 | public final static short SW_ArrayStoreException = (short) 0xff04; 30 | public final static short SW_NullPointerException = (short) 0xff05; 31 | public final static short SW_NegativeArraySizeException = (short) 0xff06; 32 | public final static short SW_CryptoException_prefix = (short) 0xf100; 33 | public final static short SW_SystemException_prefix = (short) 0xf200; 34 | public final static short SW_PINException_prefix = (short) 0xf300; 35 | public final static short SW_TransactionException_prefix = (short) 0xf400; 36 | public final static short SW_CardRuntimeException_prefix = (short) 0xf500; 37 | } 38 | -------------------------------------------------------------------------------- /MPCApplet/src/mpc/StateModel.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import javacard.framework.ISOException; 4 | 5 | /** 6 | * 7 | * @author Petr Svenda 8 | */ 9 | public class StateModel { 10 | private short STATE_KEYGEN = STATE_UNINITIALIZED; 11 | 12 | // Protocol state constants 13 | public static final short STATE_UNINITIALIZED = (short) -1; 14 | public static final short STATE_QUORUM_CLEARED = (short) 0; 15 | public static final short STATE_QUORUM_INITIALIZED = (short) 1; 16 | public static final short STATE_KEYGEN_CLEARED = (short) 2; 17 | public static final short STATE_KEYGEN_PRIVATEGENERATED = (short) 3; 18 | public static final short STATE_KEYGEN_COMMITMENTSCOLLECTED = (short) 4; 19 | public static final short STATE_KEYGEN_SHARESCOLLECTED = (short) 5; 20 | public static final short STATE_KEYGEN_KEYPAIRGENERATED = (short) 6; 21 | 22 | 23 | public static final short FNC_QuorumContext_GetXi = (short) 0xf001; 24 | public static final short FNC_QuorumContext_GetYi = (short) 0xf002; 25 | public static final short FNC_QuorumContext_Invalidate = (short) 0xf003; 26 | public static final short FNC_QuorumContext_GetY = (short) 0xf004; 27 | public static final short FNC_QuorumContext_RetrieveCommitment = (short) 0xf005; 28 | public static final short FNC_QuorumContext_SetYs = (short) 0xf006; 29 | public static final short FNC_QuorumContext_StoreCommitment = (short) 0xf007; 30 | public static final short FNC_QuorumContext_GenerateExampleBackdooredKeyPair = (short) 0xf008; 31 | public static final short FNC_QuorumContext_InitAndGenerateKeyPair = (short) 0xf009; 32 | public static final short FNC_QuorumContext_GetState = (short) 0xf00a; 33 | public static final short FNC_QuorumContext_Reset = (short) 0xf00b; 34 | public static final short FNC_QuorumContext_SetupNew = (short) 0xf00c; 35 | 36 | 37 | public static final short FNC_QuorumContext_Encrypt = (short) 0xf010; 38 | public static final short FNC_QuorumContext_DecryptShare = (short) 0xf011; 39 | public static final short FNC_QuorumContext_Sign_RetrieveRandomRi = (short) 0xf012; 40 | public static final short FNC_QuorumContext_Sign = (short) 0xf013; 41 | public static final short FNC_QuorumContext_Sign_GetCurrentCounter = (short) 0xf014; 42 | 43 | 44 | public static final short FNC_QuorumContext_VerifyCallerAuthorization = (short) 0xf011; 45 | 46 | public static final short FNC_QuorumContext_GenerateRandomData = (short) 0xf012; 47 | 48 | 49 | 50 | 51 | public void CheckAllowedFunction(short requestedFnc) { 52 | CheckAllowedFunction(requestedFnc, STATE_KEYGEN); 53 | } 54 | 55 | public short MakeStateTransition(short newState) { 56 | STATE_KEYGEN = MakeStateTransition(STATE_KEYGEN, newState); 57 | return STATE_KEYGEN; 58 | } 59 | 60 | public short GetState() { 61 | return STATE_KEYGEN; 62 | } 63 | 64 | private static void CheckAllowedFunction(short requestedFnc, short currentState) { 65 | // Check for functions which can be called from any state 66 | switch (requestedFnc) { 67 | case FNC_QuorumContext_Reset: return; 68 | case FNC_QuorumContext_GetState: return; 69 | case FNC_QuorumContext_Invalidate: return; 70 | } 71 | 72 | // Check if function can be called from current state 73 | switch (currentState) { 74 | case STATE_QUORUM_CLEARED: 75 | if (requestedFnc == FNC_QuorumContext_SetupNew) return; 76 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); // if reached, function is not allowed in given state 77 | break; 78 | 79 | case STATE_QUORUM_INITIALIZED: 80 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); // if reached, function is not allowed in given state 81 | break; 82 | 83 | case STATE_KEYGEN_CLEARED: 84 | if (requestedFnc == FNC_QuorumContext_InitAndGenerateKeyPair) return; 85 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); 86 | break; 87 | 88 | case STATE_KEYGEN_PRIVATEGENERATED: 89 | if (requestedFnc == FNC_QuorumContext_RetrieveCommitment) return; 90 | if (requestedFnc == FNC_QuorumContext_StoreCommitment) return; 91 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); // if reached, function is not allowed in given state 92 | break; 93 | 94 | case STATE_KEYGEN_COMMITMENTSCOLLECTED: 95 | if (requestedFnc == FNC_QuorumContext_SetYs) return; 96 | if (requestedFnc == FNC_QuorumContext_GetYi) return; 97 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); // if reached, function is not allowed in given state 98 | break; 99 | 100 | case STATE_KEYGEN_SHARESCOLLECTED: 101 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); // if reached, function is not allowed in given state 102 | break; 103 | 104 | case STATE_KEYGEN_KEYPAIRGENERATED: 105 | if (requestedFnc == FNC_QuorumContext_GetXi) return; 106 | if (requestedFnc == FNC_QuorumContext_GetY) return; 107 | if (requestedFnc == FNC_QuorumContext_Encrypt) return; 108 | if (requestedFnc == FNC_QuorumContext_DecryptShare) return; 109 | if (requestedFnc == FNC_QuorumContext_Sign_RetrieveRandomRi) return; 110 | if (requestedFnc == FNC_QuorumContext_Sign) return; 111 | if (requestedFnc == FNC_QuorumContext_Sign_GetCurrentCounter) return; 112 | 113 | ISOException.throwIt(Consts.SW_FUNCTINNOTALLOWED); // if reached, function is not allowed in given state 114 | break; 115 | 116 | default: 117 | ISOException.throwIt(Consts.SW_UNKNOWNSTATE); 118 | break; 119 | } 120 | } 121 | 122 | 123 | private static short MakeStateTransition(short currentState, short newState) { 124 | // Check for functions which can be reached from any state 125 | switch (newState) { 126 | case STATE_QUORUM_CLEARED: 127 | return newState; 128 | } 129 | 130 | // Check if transition from currentState -> newState is allowed 131 | switch (currentState) { 132 | case STATE_QUORUM_CLEARED: 133 | if (newState == STATE_QUORUM_INITIALIZED) return newState; 134 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); // if reached, transition is not allowed 135 | break; 136 | case STATE_QUORUM_INITIALIZED: 137 | if (newState == STATE_KEYGEN_CLEARED) return newState; 138 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); // if reached, transition is not allowed 139 | break; 140 | case STATE_KEYGEN_CLEARED: 141 | if (newState == STATE_KEYGEN_PRIVATEGENERATED) return newState; 142 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); // if reached, transition is not allowed 143 | break; 144 | case STATE_KEYGEN_PRIVATEGENERATED: 145 | if (newState == STATE_KEYGEN_COMMITMENTSCOLLECTED) return newState; 146 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); 147 | break; 148 | case STATE_KEYGEN_COMMITMENTSCOLLECTED: 149 | if (newState == STATE_KEYGEN_SHARESCOLLECTED) return newState; 150 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); 151 | break; 152 | case STATE_KEYGEN_SHARESCOLLECTED: 153 | if (newState == STATE_KEYGEN_KEYPAIRGENERATED) return newState; 154 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); 155 | break; 156 | case STATE_KEYGEN_KEYPAIRGENERATED: 157 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); 158 | break; 159 | default: 160 | ISOException.throwIt(Consts.SW_UNKNOWNSTATE); 161 | break; 162 | } 163 | ISOException.throwIt(Consts.SW_INCORRECTSTATETRANSITION); 164 | return newState; 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /MPCTestClient/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project MPCClient. 12 | 13 | 60 | 61 | 62 | 63 | 67 | 68 | -------------------------------------------------------------------------------- /MPCTestClient/dist/README.TXT: -------------------------------------------------------------------------------- 1 | ======================== 2 | BUILD OUTPUT DESCRIPTION 3 | ======================== 4 | 5 | When you build an Java application project that has a main class, the IDE 6 | automatically copies all of the JAR 7 | files on the projects classpath to your projects dist/lib folder. The IDE 8 | also adds each of the JAR files to the Class-Path element in the application 9 | JAR files manifest file (MANIFEST.MF). 10 | 11 | To run the project from the command line, go to the dist folder and 12 | type the following: 13 | 14 | java -jar "MPCTestClient.jar" 15 | 16 | To distribute this project, zip up the dist folder (including the lib folder) 17 | and distribute the ZIP file. 18 | 19 | Notes: 20 | 21 | * If two JAR files on the project classpath have the same name, only the first 22 | JAR file is copied to the lib folder. 23 | * Only JAR files are copied to the lib folder. 24 | If the classpath contains other types of files or folders, these files (folders) 25 | are not copied. 26 | * If a library on the projects classpath also has a Class-Path element 27 | specified in the manifest,the content of the Class-Path element has to be on 28 | the projects runtime path. 29 | * To set a main class in a standard Java project, right-click the project node 30 | in the Projects window and choose Properties. Then click Run and enter the 31 | class name in the Main Class field. Alternatively, you can manually type the 32 | class name in the manifest Main-Class element. 33 | -------------------------------------------------------------------------------- /MPCTestClient/libs/bcprov-jdk15on-155.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCTestClient/libs/bcprov-jdk15on-155.jar -------------------------------------------------------------------------------- /MPCTestClient/libs/bignat.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCTestClient/libs/bignat.jar -------------------------------------------------------------------------------- /MPCTestClient/libs/jcardsim-3.0.5-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCTestClient/libs/jcardsim-3.0.5-SNAPSHOT.jar -------------------------------------------------------------------------------- /MPCTestClient/libs/offcard.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenCryptoProject/Myst/a75a14dde644e4aa5e7e5e1276599b8d878b5714/MPCTestClient/libs/offcard.jar -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/CardMPCPlayer.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import ds.ov2.bignat.Bignat; 4 | import java.math.BigInteger; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.util.HashMap; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | import javax.smartcardio.CardChannel; 10 | import javax.smartcardio.CardException; 11 | import javax.smartcardio.CommandAPDU; 12 | import javax.smartcardio.ResponseAPDU; 13 | import mpc.Consts; 14 | import org.bouncycastle.math.ec.ECCurve; 15 | import org.bouncycastle.math.ec.ECPoint; 16 | 17 | /** 18 | * 19 | * @author Petr Svenda 20 | */ 21 | public class CardMPCPlayer implements MPCPlayer { 22 | 23 | static class QuorumContext { 24 | 25 | short playerIndex; 26 | short quorumIndex = 0; 27 | short numPlayers = 0; 28 | BigInteger card_e_BI; 29 | public byte[] pub_key_Hash; 30 | ECPoint pubKey; 31 | ECPoint AggPubKey; 32 | 33 | QuorumContext(short quorumIndex, short playerIndex, short numPlayers) { 34 | this.quorumIndex = quorumIndex; 35 | this.playerIndex = playerIndex; 36 | this.numPlayers = numPlayers; 37 | } 38 | } 39 | CardChannel channel = null; 40 | String logFormat = "%-40s:%s%n\n-------------------------------------------------------------------------------\n"; 41 | Long lastTransmitTime; 42 | boolean bFailOnAssert = true; 43 | HashMap quorumsCtxMap; 44 | ECCurve curve; 45 | 46 | CardMPCPlayer(CardChannel channel, String logFormat, Long lastTransmitTime, boolean bFailOnAssert, ECCurve curve) { 47 | this.channel = channel; 48 | this.logFormat = logFormat; 49 | this.lastTransmitTime = lastTransmitTime; 50 | this.bFailOnAssert = bFailOnAssert; 51 | this.quorumsCtxMap = new HashMap<>(); 52 | this.curve = curve; 53 | } 54 | 55 | // 56 | // MPCPlayer methods 57 | // 58 | @Override 59 | public short GetPlayerIndex(short quorumIndex) { 60 | return quorumsCtxMap.get(quorumIndex).playerIndex; 61 | } 62 | 63 | @Override 64 | public byte[] GetPubKeyHash(short quorumIndex) { 65 | return quorumsCtxMap.get(quorumIndex).pub_key_Hash; 66 | } 67 | 68 | @Override 69 | public BigInteger GetE(short quorumIndex) { 70 | return quorumsCtxMap.get(quorumIndex).card_e_BI; 71 | } 72 | 73 | @Override 74 | public ECPoint GetPubKey(short quorumIndex) { 75 | return quorumsCtxMap.get(quorumIndex).pubKey; 76 | } 77 | 78 | @Override 79 | public ECPoint GetAggregatedPubKey(short quorumIndex) { 80 | return quorumsCtxMap.get(quorumIndex).AggPubKey; 81 | } 82 | 83 | @Override 84 | public byte[] Gen_Rin(short quorumIndex, short i) throws NoSuchAlgorithmException, Exception { 85 | byte[] rin = RetrieveRI(channel, quorumIndex, i); 86 | System.out.format(logFormat, "Retrieve Ri,n (INS_SIGN_RETRIEVE_RI):", Util.bytesToHex(rin)); 87 | return rin; 88 | } 89 | 90 | @Override 91 | public void disconnect() { 92 | try { 93 | channel.getCard().disconnect(true); // Disconnect from the card 94 | } catch (CardException ex) { 95 | Logger.getLogger(CardMPCPlayer.class.getName()).log(Level.SEVERE, null, ex); 96 | } 97 | } 98 | 99 | // 100 | // CardMPCPlayer public methods 101 | // 102 | public void SetBackdoorExample(CardChannel channel, boolean bMakeBackdoored) 103 | throws Exception { 104 | 105 | CommandAPDU cmd; 106 | if (bMakeBackdoored) { 107 | // If to be backdoored, set p1 to 0x55 108 | cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SET_BACKDOORED_EXAMPLE, 0x55, 0x00, 0x00); 109 | } else { 110 | cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SET_BACKDOORED_EXAMPLE, 0x00, 0x00, 0x00); 111 | } 112 | ResponseAPDU response = transmit(channel, cmd); 113 | } 114 | 115 | public boolean GetCardInfo() throws Exception { 116 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_PERSONALIZE_GETCARDINFO, 0, 0); 117 | ResponseAPDU response = transmit(channel, cmd); 118 | 119 | // Parse response 120 | if (response.getSW() == (Consts.SW_SUCCESS & 0xffff)) { 121 | int offset = 0; 122 | byte[] data = response.getData(); 123 | System.out.println("---CARD STATE -------"); 124 | assert (data[offset] == Consts.TLV_TYPE_CARDUNIQUEDID); 125 | offset++; 126 | short len = Util.getShort(data, offset); 127 | offset += 2; 128 | System.out.println(String.format("CardIDLong:\t\t\t %s", Util.toHex(data, offset, len))); 129 | offset += len; 130 | 131 | assert (data[offset] == Consts.TLV_TYPE_KEYPAIR_STATE); 132 | offset++; 133 | assert (Util.getShort(data, offset) == 2); 134 | offset += 2; 135 | System.out.println(String.format("KeyPair state:\t\t\t %d", Util.getShort(data, offset))); 136 | offset += 2; 137 | assert (data[offset] == Consts.TLV_TYPE_EPHIMERAL_STATE); 138 | offset++; 139 | assert (Util.getShort(data, offset) == 2); 140 | offset += 2; 141 | System.out.println(String.format("EphiKey state:\t\t\t %d", Util.getShort(data, offset))); 142 | offset += 2; 143 | 144 | assert (data[offset] == Consts.TLV_TYPE_MEMORY); 145 | offset++; 146 | assert (Util.getShort(data, offset) == 6); 147 | offset += 2; 148 | System.out.println(String.format("MEMORY_PERSISTENT:\t\t %d bytes", Util.getShort(data, offset))); 149 | offset += 2; 150 | System.out.println(String.format("MEMORY_TRANSIENT_RESET:\t\t %d bytes", Util.getShort(data, offset))); 151 | offset += 2; 152 | System.out.println(String.format("MEMORY_TRANSIENT_DESELECT:\t %d bytes", Util.getShort(data, offset))); 153 | offset += 2; 154 | System.out.println("-----------------"); 155 | 156 | assert (data[offset] == Consts.TLV_TYPE_COMPILEFLAGS); 157 | offset++; 158 | assert (Util.getShort(data, offset) == 4); 159 | offset += 2; 160 | System.out.println(String.format("Consts.MAX_N_PLAYERS:\t\t %d", Util.getShort(data, offset))); 161 | offset += 2; 162 | System.out.println(String.format("DKG.PLAYERS_IN_RAM:\t\t %b", (data[offset] == 0) ? false : true)); 163 | offset++; 164 | System.out.println(String.format("DKG.COMPUTE_Y_ONTHEFLY:\t\t %b ", (data[offset] == 0) ? false : true)); 165 | offset++; 166 | System.out.println("-----------------"); 167 | 168 | assert (data[offset] == Consts.TLV_TYPE_GITCOMMIT); 169 | offset++; 170 | len = Util.getShort(data, offset); 171 | assert (len == 4); 172 | offset += 2; 173 | System.out.println(String.format("Git commit tag:\t\t\t 0x%s", Util.toHex(data, offset, len))); 174 | offset += len; 175 | System.out.println("-----------------"); 176 | 177 | assert (data[offset] == Consts.TLV_TYPE_EXAMPLEBACKDOOR); 178 | offset++; 179 | len = Util.getShort(data, offset); 180 | assert (len == 1); 181 | offset += 2; 182 | if (data[offset] == (byte) 0) { 183 | System.out.println("Applet is in normal (non-backdoored) state"); 184 | } else { 185 | System.out.println("WARNING: Applet is in example 'backdoored' state with fixed private key"); 186 | } 187 | offset += len; 188 | System.out.println("-----------------"); 189 | } 190 | 191 | return checkSW(response); 192 | } 193 | 194 | private byte[] RetrieveRI(CardChannel channel, short quorumIndex, short i) throws Exception { 195 | byte[] packetData = preparePacketData(Consts.INS_SIGN_RETRIEVE_RI, quorumIndex, (short) i); 196 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SIGN_RETRIEVE_RI, 197 | 0x00, 0x00, packetData); 198 | ResponseAPDU response = transmit(channel, cmd); 199 | 200 | ///We do nothing with the key, as we just use the Aggregated R in the test cases 201 | // return checkSW(response); 202 | return response.getData(); 203 | } 204 | 205 | private ResponseAPDU transmit(CardChannel channel, CommandAPDU cmd) 206 | throws CardException { 207 | log(cmd); 208 | 209 | long elapsed = -System.currentTimeMillis(); 210 | ResponseAPDU response = channel.transmit(cmd); 211 | elapsed += System.currentTimeMillis(); 212 | lastTransmitTime = elapsed; 213 | log(response, elapsed); 214 | 215 | return response; 216 | } 217 | 218 | private void log(CommandAPDU cmd) { 219 | System.out.printf("--> %s\n", Util.toHex(cmd.getBytes()), 220 | cmd.getBytes().length); 221 | } 222 | 223 | private void log(ResponseAPDU response, long time) { 224 | String swStr = String.format("%02X", response.getSW()); 225 | byte[] data = response.getData(); 226 | if (data.length > 0) { 227 | System.out.printf("<-- %s %s (%d)\n", Util.toHex(data), swStr, 228 | data.length); 229 | } else { 230 | System.out.printf("<-- %s\n", swStr); 231 | } 232 | if (time > 0) { 233 | System.out.printf(String.format("Elapsed time %d ms\n", time)); 234 | } 235 | } 236 | 237 | private void log(ResponseAPDU response) { 238 | log(response, 0); 239 | } 240 | 241 | byte[] preparePacketData(byte operationCode, short param1) { 242 | return preparePacketData(operationCode, 1, param1, null, null); 243 | } 244 | 245 | byte[] preparePacketData(byte operationCode, short param1, short param2) { 246 | return preparePacketData(operationCode, 2, param1, param2, null); 247 | } 248 | 249 | byte[] preparePacketData(byte operationCode, short param1, short param2, short param3) { 250 | return preparePacketData(operationCode, 3, param1, param2, param3); 251 | } 252 | 253 | static byte[] preparePacketData(byte operationCode, int numShortParams, Short param1, Short param2, Short param3) { 254 | int offset = 0; 255 | byte[] cmd = new byte[1 + 2 + 1 + 2 + numShortParams * 2]; 256 | cmd[offset] = Consts.TLV_TYPE_MPCINPUTPACKET; 257 | offset++; 258 | Util.shortToByteArray((short) (cmd.length - 3), cmd, offset); 259 | offset += 2; 260 | cmd[offset] = operationCode; 261 | offset++; 262 | Util.shortToByteArray((short) (2 * 2), cmd, offset); 263 | offset += 2; 264 | if (numShortParams >= 1) { 265 | offset = Util.shortToByteArray(param1, cmd, offset); 266 | } 267 | if (numShortParams >= 2) { 268 | offset = Util.shortToByteArray(param2, cmd, offset); 269 | } 270 | if (numShortParams >= 3) { 271 | offset = Util.shortToByteArray(param3, cmd, offset); 272 | } 273 | 274 | return cmd; 275 | } 276 | 277 | @Override 278 | public boolean Setup(short quorumIndex, short numPlayers, short thisPlayerIndex) throws Exception { 279 | quorumsCtxMap.put(quorumIndex, new QuorumContext(quorumIndex, thisPlayerIndex, numPlayers)); 280 | 281 | byte[] packetData = preparePacketData(Consts.INS_QUORUM_SETUP_NEW, quorumIndex, numPlayers, thisPlayerIndex); 282 | 283 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_QUORUM_SETUP_NEW, 0, 284 | 0, packetData); 285 | ResponseAPDU response = transmit(channel, cmd); 286 | 287 | return checkSW(response); 288 | } 289 | 290 | @Override 291 | public boolean Reset(short quorumIndex) throws Exception { 292 | byte[] packetData = preparePacketData(Consts.INS_QUORUM_RESET, quorumIndex); 293 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_QUORUM_RESET, 0x00, 0x00, packetData); 294 | ResponseAPDU response = transmit(channel, cmd); 295 | return checkSW(response); 296 | } 297 | 298 | @Override 299 | public boolean GenKeyPair(short quorumIndex) throws Exception { 300 | byte[] packetData = preparePacketData(Consts.INS_KEYGEN_INIT, quorumIndex); 301 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_KEYGEN_INIT, 0x00, 302 | 0x00, packetData); 303 | ResponseAPDU response = transmit(channel, cmd); 304 | return checkSW(response); 305 | } 306 | 307 | @Override 308 | public boolean RetrievePubKeyHash(short quorumIndex) throws Exception { 309 | byte[] packetData = preparePacketData(Consts.INS_KEYGEN_RETRIEVE_COMMITMENT, quorumIndex); 310 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_KEYGEN_RETRIEVE_COMMITMENT, 311 | 0x00, 0x00, packetData); 312 | ResponseAPDU response = transmit(channel, cmd); 313 | quorumsCtxMap.get(quorumIndex).pub_key_Hash = response.getData(); // Store pub key hash 314 | 315 | return checkSW(response); 316 | } 317 | 318 | @Override 319 | public boolean StorePubKeyHash(short quorumIndex, short id, 320 | byte[] hash_arr) throws Exception { 321 | byte[] packetData = preparePacketData(Consts.INS_KEYGEN_STORE_COMMITMENT, quorumIndex, id, (short) hash_arr.length); 322 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_KEYGEN_STORE_COMMITMENT, 323 | 0x00, 0x00, Util.concat(packetData, hash_arr)); 324 | ResponseAPDU response = transmit(channel, cmd); 325 | return checkSW(response); 326 | } 327 | 328 | @Override 329 | public boolean StorePubKey(short quorumIndex, short id, 330 | byte[] pub_arr) throws Exception { 331 | byte[] packetData = preparePacketData(Consts.INS_KEYGEN_STORE_PUBKEY, quorumIndex, id, (short) pub_arr.length); 332 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_KEYGEN_STORE_PUBKEY, 333 | 0x00, 0x00, Util.concat(packetData, pub_arr)); 334 | ResponseAPDU response = transmit(channel, cmd); 335 | return checkSW(response); 336 | } 337 | 338 | @Override 339 | public byte[] RetrievePubKey(short quorumIndex) throws Exception { 340 | byte[] packetData = preparePacketData(Consts.INS_KEYGEN_RETRIEVE_PUBKEY, quorumIndex); 341 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, 342 | Consts.INS_KEYGEN_RETRIEVE_PUBKEY, 0x00, 0x00, packetData); 343 | ResponseAPDU response = transmit(channel, cmd); 344 | 345 | quorumsCtxMap.get(quorumIndex).pubKey = Util.ECPointDeSerialization(curve, response.getData(), 0); // Store Pub 346 | 347 | return response.getData(); 348 | } 349 | 350 | @Override 351 | public boolean RetrieveAggPubKey(short quorumIndex) 352 | throws Exception { 353 | byte[] packetData = preparePacketData(Consts.INS_KEYGEN_RETRIEVE_AGG_PUBKEY, quorumIndex); 354 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, 355 | Consts.INS_KEYGEN_RETRIEVE_AGG_PUBKEY, 0x00, 0x00, packetData); 356 | ResponseAPDU response = transmit(channel, cmd); 357 | 358 | quorumsCtxMap.get(quorumIndex).AggPubKey = Util.ECPointDeSerialization(curve, response.getData(), 0); // Store aggregated pub 359 | 360 | return checkSW(response); 361 | } 362 | 363 | @Override 364 | public byte[] Encrypt(short quorumIndex, byte[] plaintext) 365 | throws Exception { 366 | byte[] packetData = preparePacketData(Consts.INS_ENCRYPT, quorumIndex, (short) plaintext.length); 367 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_ENCRYPT, 0x0, 0x0, Util.concat(packetData, plaintext)); 368 | ResponseAPDU response = transmit(channel, cmd); 369 | return response.getData(); 370 | } 371 | 372 | @Override 373 | public byte[] Decrypt(short quorumIndex, byte[] ciphertext) throws Exception { 374 | byte[] packetData = preparePacketData(Consts.INS_DECRYPT, quorumIndex, (short) ciphertext.length); 375 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_DECRYPT, 0x0, 0x0, Util.concat(packetData, ciphertext)); 376 | ResponseAPDU response = transmit(channel, cmd); 377 | 378 | return response.getData(); 379 | } 380 | 381 | @Override 382 | public BigInteger Sign(short quorumIndex, int round, byte[] plaintext, byte[] Rn) throws Exception { 383 | 384 | //String operationName = String.format("Signature(%s) (INS_SIGN)", msgToSign.toString()); 385 | byte[] signature = Sign_plain(quorumIndex, round, plaintext, Rn); 386 | 387 | //Parse s from Card 388 | Bignat card_s_Bn = new Bignat((short) 32, false); 389 | card_s_Bn.from_byte_array((short) 32, (short) 0, signature, (short) 0); 390 | BigInteger card_s_bi = new BigInteger(1, card_s_Bn.as_byte_array()); 391 | 392 | //Parse e from Card 393 | Bignat card_e_Bn = new Bignat((short) 32, false); 394 | card_e_Bn.from_byte_array((short) 32, (short) 0, signature, (short) 32); 395 | quorumsCtxMap.get(quorumIndex).card_e_BI = new BigInteger(1, card_e_Bn.as_byte_array()); 396 | 397 | //System.out.println("REALCARD : s: " + bytesToHex(card_s_Bn.as_byte_array())); 398 | //System.out.println("REALCARD : e: " + bytesToHex(card_e_Bn.as_byte_array()) + "\n"); 399 | return card_s_bi; 400 | } 401 | 402 | public byte[] Sign_plain(short quorumIndex, int round, byte[] plaintext, byte[] Rn) throws Exception { 403 | byte[] packetData = preparePacketData(Consts.INS_SIGN, quorumIndex, (short) round, (short) ((short) plaintext.length + (short) Rn.length)); 404 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SIGN, round, 0x0, Util.concat(packetData, Util.concat(plaintext, Rn))); 405 | ResponseAPDU response = transmit(channel, cmd); 406 | 407 | return response.getData(); 408 | } 409 | 410 | private boolean checkSW(ResponseAPDU response) { 411 | if (response.getSW() != (Consts.SW_SUCCESS & 0xffff)) { 412 | System.err.printf("Received error status: %02X.\n", 413 | response.getSW()); 414 | if (bFailOnAssert) { 415 | assert (false); // break on error 416 | } 417 | return false; 418 | } 419 | return true; 420 | } 421 | 422 | private boolean TestNativeECAdd(CardChannel channel, ECPoint point1, ECPoint point2) throws Exception { 423 | // addPoint 424 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_TESTECC, (byte) 1, point1.getEncoded(false).length, Util.concat(point1.getEncoded(false), point2.getEncoded(false))); 425 | ResponseAPDU response = transmit(channel, cmd); 426 | return checkSW(response); 427 | } 428 | 429 | private boolean TestNativeECMult(CardChannel channel, ECPoint point1, BigInteger scalar) throws Exception { 430 | // multiply by scalar 431 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_TESTECC, (byte) 2, point1.getEncoded(false).length, Util.concat(point1.getEncoded(false), scalar.toByteArray())); 432 | ResponseAPDU response = transmit(channel, cmd); 433 | return checkSW(response); 434 | } 435 | 436 | /* Debug only, not supported on real card 437 | private boolean RetrievePrivKey_DebugOnly(CardChannel channel) 438 | throws Exception { 439 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, 440 | Consts.BUGBUG_INS_KEYGEN_RETRIEVE_PRIVKEY, 0x0, 0x0); 441 | ResponseAPDU response = transmit(channel, cmd); 442 | 443 | // Store Secret 444 | Bignat tmp_BN = new Bignat(Consts.SHARE_BASIC_SIZE, false); 445 | tmp_BN.from_byte_array(Consts.SHARE_BASIC_SIZE, (short) 0, (response.getData()), 446 | (short) 0); 447 | mpcGlobals.secret = Convenience.bi_from_bn(tmp_BN); 448 | 449 | return checkSW(response); 450 | } 451 | */ 452 | /* 453 | private byte[] Encrypt(CardChannel channel, short quorumIndex, byte[] plaintext, MPCRunConfig runCfg, boolean bProfilePerf) 454 | throws Exception { 455 | byte[] packetData = preparePacketData(Consts.INS_ENCRYPT, quorumIndex, (short) plaintext.length); 456 | if (!bProfilePerf) { 457 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_ENCRYPT, 0x0, 0x0, Util.concat(packetData, plaintext)); 458 | ResponseAPDU response = transmit(channel, cmd); 459 | return response.getData(); 460 | } else { 461 | transmit(channel, new CommandAPDU(PERF_COMMAND_NONE)); // erase any previous performance stop 462 | 463 | short[] PERFSTOPS_Encrypt = {PM.TRAP_CRYPTOPS_ENCRYPT_1, PM.TRAP_CRYPTOPS_ENCRYPT_2, PM.TRAP_CRYPTOPS_ENCRYPT_3, PM.TRAP_CRYPTOPS_ENCRYPT_4, PM.TRAP_CRYPTOPS_ENCRYPT_5, PM.TRAP_CRYPTOPS_ENCRYPT_6, PM.TRAP_CRYPTOPS_ENCRYPT_COMPLETE}; 464 | runCfg.perfStops = PERFSTOPS_Encrypt; 465 | runCfg.perfStopComplete = PM.TRAP_CRYPTOPS_ENCRYPT_COMPLETE; 466 | long avgOpTime = 0; 467 | String opName = "Encrypt: "; 468 | for (int repeat = 0; repeat < runCfg.numSingleOpRepeats; repeat++) { 469 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_ENCRYPT, 0x0, 0x0, Util.concat(packetData, plaintext)); 470 | avgOpTime += PerfAnalyzeCommand(opName, cmd, channel, runCfg); 471 | } 472 | System.out.println(String.format("%s: average time: %d", opName, avgOpTime / runCfg.numSingleOpRepeats)); 473 | transmit(channel, new CommandAPDU(PERF_COMMAND_NONE)); // erase any previous performance stop 474 | 475 | return Encrypt(channel, quorumIndex, plaintext, runCfg, false); 476 | } 477 | } 478 | */ 479 | /* 480 | 481 | private byte[] Decrypt(CardChannel channel, short quorumIndex, byte[] ciphertext, MPCRunConfig runCfg, boolean bProfilePerf) 482 | throws Exception { 483 | byte[] packetData = preparePacketData(Consts.INS_DECRYPT, quorumIndex, (short) ciphertext.length); 484 | if (!bProfilePerf) { 485 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_DECRYPT, 0x0, 0x0, Util.concat(packetData, ciphertext)); 486 | ResponseAPDU response = transmit(channel, cmd); 487 | 488 | return response.getData(); 489 | } else { 490 | transmit(channel, new CommandAPDU(PERF_COMMAND_NONE)); // erase any previous performance stop 491 | 492 | short[] PERFSTOPS_Decrypt = {PM.TRAP_CRYPTOPS_DECRYPTSHARE_1, PM.TRAP_CRYPTOPS_DECRYPTSHARE_2, PM.TRAP_CRYPTOPS_DECRYPTSHARE_COMPLETE}; 493 | runCfg.perfStops = PERFSTOPS_Decrypt; 494 | runCfg.perfStopComplete = PM.TRAP_CRYPTOPS_DECRYPTSHARE_COMPLETE; 495 | long avgOpTime = 0; 496 | String opName = "Decrypt: "; 497 | for (int repeat = 0; repeat < runCfg.numSingleOpRepeats; repeat++) { 498 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_DECRYPT, 0x0, 0x0, Util.concat(packetData, ciphertext)); 499 | avgOpTime += PerfAnalyzeCommand(opName, cmd, channel, runCfg); 500 | } 501 | System.out.println(String.format("%s: average time: %d", opName, avgOpTime / runCfg.numSingleOpRepeats)); 502 | transmit(channel, new CommandAPDU(PERF_COMMAND_NONE)); // erase any previous performance stop 503 | 504 | return Decrypt(channel, quorumIndex, ciphertext, runCfg, false); 505 | } 506 | } 507 | */ 508 | /* 509 | public byte[] Sign_profilePerf(short quorumIndex, int round, byte[] plaintext, byte[] Rn, MPCRunConfig runCfg, boolean bProfilePerf) throws Exception { 510 | // Repeated measurements if required 511 | long elapsed = -System.currentTimeMillis(); 512 | int repeats = 100000; 513 | for (int i = 1; i < repeats; i++) { 514 | plaintext[5] = (byte) (i % 256); 515 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SIGN, round, 0x0, concat(plaintext, Rn)); 516 | ResponseAPDU response = transmit(channel, cmd); 517 | } 518 | elapsed += System.currentTimeMillis(); 519 | System.out.format("Elapsed: %d ms, time per Sign = %f ms\n", elapsed, elapsed / (float) repeats); 520 | 521 | byte[] packetData = preparePacketData(Consts.INS_SIGN, quorumIndex, (short) round, (short) ((short) plaintext.length + (short) Rn.length)); 522 | if (!bProfilePerf) { 523 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SIGN, round, 0x0, Util.concat(packetData, Util.concat(plaintext, Rn))); 524 | ResponseAPDU response = transmit(channel, cmd); 525 | 526 | return response.getData(); 527 | } else { 528 | // Repeated measurements if required 529 | transmit(channel, new CommandAPDU(PERF_COMMAND_NONE)); // erase any previous performance stop 530 | 531 | short[] PERFSTOPS_Decrypt = {PM.TRAP_CRYPTOPS_SIGN_1, PM.TRAP_CRYPTOPS_SIGN_2, PM.TRAP_CRYPTOPS_SIGN_3, PM.TRAP_CRYPTOPS_SIGN_4, PM.TRAP_CRYPTOPS_SIGN_5, PM.TRAP_CRYPTOPS_SIGN_6, PM.TRAP_CRYPTOPS_SIGN_7, PM.TRAP_CRYPTOPS_SIGN_8, PM.TRAP_CRYPTOPS_SIGN_9, PM.TRAP_CRYPTOPS_SIGN_10, PM.TRAP_CRYPTOPS_SIGN_COMPLETE}; 532 | runCfg.perfStops = PERFSTOPS_Decrypt; 533 | runCfg.perfStopComplete = PM.TRAP_CRYPTOPS_SIGN_COMPLETE; 534 | long avgOpTime = 0; 535 | String opName = "Sign: "; 536 | for (int repeat = 0; repeat < runCfg.numSingleOpRepeats; repeat++) { 537 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_SIGN, round, 0x0, Util.concat(packetData, Util.concat(plaintext, Rn))); 538 | avgOpTime += PerfAnalyzeCommand(opName, cmd, channel, runCfg); 539 | } 540 | System.out.println(String.format("%s: average time: %d", opName, avgOpTime / runCfg.numSingleOpRepeats)); 541 | transmit(channel, new CommandAPDU(PERF_COMMAND_NONE)); // erase any previous performance stop 542 | 543 | return Sign(channel, quorumIndex, round, plaintext, Rn, runCfg, false); 544 | } 545 | } 546 | /**/ 547 | /* 548 | private boolean PointAdd(CardChannel channel) throws Exception { 549 | byte[] PointA = mpcGlobals.G.multiply(BigInteger.valueOf(10)).getEncoded(false); 550 | byte[] PointB = mpcGlobals.G.multiply(BigInteger.valueOf(20)).getEncoded(false); 551 | 552 | CommandAPDU cmd = new CommandAPDU(Consts.CLA_MPC, Consts.INS_ADDPOINTS, 0x00, 0x00, Util.concat(PointA, PointB)); 553 | ResponseAPDU response = transmit(channel, cmd); 554 | return checkSW(response); 555 | } 556 | */ 557 | } 558 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/CardManagement.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import com.licel.jcardsim.io.CAD; 4 | import com.licel.jcardsim.io.JavaxSmartCardInterface; 5 | import java.util.ArrayList; 6 | import javacard.framework.AID; 7 | import javacard.framework.ISO7816; 8 | import javax.smartcardio.Card; 9 | import javax.smartcardio.CardChannel; 10 | import javax.smartcardio.CardException; 11 | import javax.smartcardio.CardTerminal; 12 | import javax.smartcardio.CommandAPDU; 13 | import javax.smartcardio.ResponseAPDU; 14 | import javax.smartcardio.TerminalFactory; 15 | 16 | public class CardManagement { 17 | 18 | static Long m_lastTransmitTime = new Long(0); 19 | 20 | // Card Logistics 21 | private static CardChannel Connect(MPCRunConfig runCfg) throws Exception { 22 | switch (runCfg.testCardType) { 23 | case PHYSICAL: { 24 | return ConnectPhysicalCard(runCfg.targetReaderIndex, runCfg.appletAID); 25 | } 26 | case JCOPSIM: { 27 | return ConnectJCOPSimulator(runCfg.targetReaderIndex, runCfg.appletAID); 28 | } 29 | case JCARDSIMLOCAL: { 30 | return ConnectJCardSimLocalSimulator(runCfg.appletToSimulate, runCfg.appletAID); 31 | } 32 | case JCARDSIMREMOTE: { 33 | return null; // Not implemented yet 34 | } 35 | default: 36 | return null; 37 | } 38 | 39 | } 40 | 41 | public static void ConnectAllPhysicalCards(byte[] appletAID, ArrayList cardsList) throws Exception { 42 | System.out.print("Looking for physical cards... "); 43 | connectToAllCardsByTerminalFactory(TerminalFactory.getDefault(), appletAID, cardsList); 44 | } 45 | 46 | private static void connectToAllCardsByTerminalFactory(TerminalFactory factory, byte[] appAID, ArrayList cardsList) throws CardException { 47 | ArrayList terminals = new ArrayList<>(); 48 | 49 | Card card = null; 50 | try { 51 | for (CardTerminal t : factory.terminals().list()) { 52 | terminals.add(t); 53 | if (t.isCardPresent()) { 54 | System.out.print("Connecting..."); 55 | card = t.connect("*"); // Connect with the card 56 | 57 | System.out.println(" Done."); 58 | 59 | System.out.print("Establishing channel..."); 60 | CardChannel channel = card.getBasicChannel(); 61 | 62 | System.out.println(" Done."); 63 | 64 | // Select applet (mpcapplet) 65 | System.out.println("Smartcard: Selecting applet..."); 66 | CommandAPDU cmd = new CommandAPDU(appAID); 67 | ResponseAPDU response = transmit(channel, cmd); 68 | 69 | if (response.getSW() == (ISO7816.SW_NO_ERROR & 0xffff)) { 70 | cardsList.add(channel); 71 | } 72 | } 73 | } 74 | } catch (Exception e) { 75 | System.out.println("Failed."); 76 | } 77 | 78 | System.out.println("MPC cards found: " + cardsList.size()); 79 | } 80 | 81 | public static CardChannel ConnectPhysicalCard(int targetReaderIndex, byte[] appletAID) throws Exception { 82 | System.out.print("Looking for physical cards... "); 83 | return connectToCardByTerminalFactory(TerminalFactory.getDefault(), targetReaderIndex, appletAID); 84 | } 85 | 86 | public static CardChannel ConnectJCOPSimulator(int targetReaderIndex, byte[] appletAID) throws Exception { 87 | // JCOP Simulators 88 | System.out.print("Looking for JCOP simulators..."); 89 | int[] ports = new int[]{8050}; 90 | return connectToCardByTerminalFactory(TerminalFactory.getInstance("JcopEmulator", ports), targetReaderIndex, appletAID); 91 | } 92 | 93 | public static CardChannel ConnectJCardSimLocalSimulator(Class appletClass, byte[] appAID) throws Exception { 94 | System.setProperty("com.licel.jcardsim.terminal.type", "2"); 95 | CAD cad = new CAD(System.getProperties()); 96 | JavaxSmartCardInterface simulator = (JavaxSmartCardInterface) cad.getCardInterface(); 97 | byte[] installData = new byte[0]; 98 | AID appletAID = new AID(appAID, (short) 0, (byte) appAID.length); 99 | 100 | AID appletAIDRes = simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); 101 | simulator.selectApplet(appletAID); 102 | return new SimulatedCardChannelLocal(simulator, appletAIDRes); 103 | } 104 | 105 | private static CardChannel connectToCardByTerminalFactory(TerminalFactory factory, int targetReaderIndex, byte[] appAID) throws CardException { 106 | ArrayList terminals = new ArrayList<>(); 107 | 108 | boolean card_found = false; 109 | CardTerminal terminal = null; 110 | Card card = null; 111 | try { 112 | for (CardTerminal t : factory.terminals().list()) { 113 | terminals.add(t); 114 | if (t.isCardPresent()) { 115 | card_found = true; 116 | } 117 | } 118 | System.out.println("Success."); 119 | } catch (Exception e) { 120 | System.out.println("Failed."); 121 | } 122 | 123 | if (card_found) { 124 | System.out.println("Cards found: " + terminals); 125 | 126 | terminal = terminals.get(targetReaderIndex); // Prioritize physical card over simulations 127 | 128 | System.out.print("Connecting..."); 129 | card = terminal.connect("*"); // Connect with the card 130 | 131 | System.out.println(" Done."); 132 | 133 | System.out.print("Establishing channel..."); 134 | CardChannel channel = card.getBasicChannel(); 135 | 136 | System.out.println(" Done."); 137 | 138 | // Select applet (mpcapplet) 139 | System.out.println("Smartcard: Selecting applet..."); 140 | 141 | CommandAPDU cmd = new CommandAPDU(appAID); 142 | 143 | ResponseAPDU response = transmit(channel, cmd); 144 | 145 | } else { 146 | System.out.print("Failed to find physical card."); 147 | } 148 | 149 | if (card != null) { 150 | return card.getBasicChannel(); 151 | } else { 152 | return null; 153 | } 154 | } 155 | 156 | public static ResponseAPDU transmit(CardChannel channel, CommandAPDU cmd) 157 | throws CardException { 158 | log(cmd); 159 | 160 | long elapsed = -System.currentTimeMillis(); 161 | ResponseAPDU response = channel.transmit(cmd); 162 | elapsed += System.currentTimeMillis(); 163 | m_lastTransmitTime = elapsed; 164 | log(response, elapsed); 165 | 166 | return response; 167 | } 168 | 169 | private static void log(CommandAPDU cmd) { 170 | System.out.printf("--> %s\n", Util.toHex(cmd.getBytes()), 171 | cmd.getBytes().length); 172 | } 173 | 174 | private static void log(ResponseAPDU response, long time) { 175 | String swStr = String.format("%02X", response.getSW()); 176 | byte[] data = response.getData(); 177 | if (data.length > 0) { 178 | System.out.printf("<-- %s %s (%d)\n", Util.toHex(data), swStr, 179 | data.length); 180 | } else { 181 | System.out.printf("<-- %s\n", swStr); 182 | } 183 | if (time > 0) { 184 | System.out.printf(String.format("Elapsed time %d ms\n", time)); 185 | } 186 | } 187 | 188 | private static void log(ResponseAPDU response) { 189 | log(response, 0); 190 | } 191 | 192 | public static boolean checkSW(ResponseAPDU response) { 193 | if (response.getSW() != (ISO7816.SW_NO_ERROR & 0xffff)) { 194 | System.err.printf("Received error status: %02X.\n", 195 | response.getSW()); 196 | return false; 197 | } 198 | return true; 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/MPCGlobals.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import java.math.BigInteger; 4 | import java.util.ArrayList; 5 | import org.bouncycastle.jce.spec.ECParameterSpec; 6 | import org.bouncycastle.math.ec.ECCurve; 7 | import org.bouncycastle.math.ec.ECPoint; 8 | 9 | /** 10 | * 11 | * @author Petr Svenda 12 | */ 13 | public class MPCGlobals { 14 | 15 | public static ECCurve curve; 16 | public static BigInteger p; 17 | public static BigInteger a; 18 | public static BigInteger b; 19 | public static BigInteger n; 20 | public static ECPoint G; 21 | public static ECParameterSpec ecSpec; 22 | 23 | public static BigInteger secret = BigInteger.valueOf(0); 24 | public static ECPoint AggPubKey; 25 | public static ECPoint R_EC; 26 | 27 | public static ECPoint c1; 28 | public static ECPoint c2; 29 | 30 | static ArrayList players = new ArrayList<>(); 31 | 32 | public static ECPoint[] Rands; 33 | } 34 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/MPCPlayer.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import java.security.NoSuchAlgorithmException; 4 | import java.math.BigInteger; 5 | import org.bouncycastle.math.ec.ECPoint; 6 | 7 | /** 8 | * 9 | * @author Petr Svenda 10 | */ 11 | public interface MPCPlayer { 12 | 13 | public BigInteger GetE(short quorumIndex); 14 | 15 | public byte[] Gen_Rin(short quorumIndex, short i) throws NoSuchAlgorithmException, Exception; 16 | 17 | public ECPoint GetPubKey(short quorumIndex); 18 | 19 | public ECPoint GetAggregatedPubKey(short quorumIndex); 20 | 21 | public short GetPlayerIndex(short quorumIndex); 22 | 23 | public byte[] GetPubKeyHash(short quorumIndex); 24 | 25 | public boolean Setup(short quorumIndex, short numPlayers, short thisPlayerIndex) throws Exception; 26 | 27 | public boolean Reset(short quorumIndex) throws Exception; 28 | 29 | public BigInteger Sign(short quorumIndex, int round, byte[] Rn, byte[] plaintext) throws Exception; 30 | 31 | public boolean GenKeyPair(short quorumIndex) throws Exception; 32 | 33 | public boolean RetrievePubKeyHash(short quorumIndex) throws Exception; 34 | 35 | public boolean StorePubKeyHash(short quorumIndex, short playerIndex, byte[] hash_arr) throws Exception; 36 | 37 | public byte[] RetrievePubKey(short quorumIndex) throws Exception; 38 | 39 | public boolean StorePubKey(short quorumIndex, short playerIndex, byte[] pub_arr) throws Exception; 40 | 41 | public boolean RetrieveAggPubKey(short quorumIndex) throws Exception; 42 | 43 | public byte[] Encrypt(short quorumIndex, byte[] plaintext) throws Exception; 44 | 45 | public byte[] Decrypt(short quorumIndex, byte[] ciphertext) throws Exception; 46 | 47 | public void disconnect(); 48 | } 49 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/MPCRunConfig.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import java.io.FileOutputStream; 4 | import java.util.ArrayList; 5 | import java.util.HashMap; 6 | import java.util.Map.Entry; 7 | import mpc.MPCApplet; 8 | 9 | /** 10 | * 11 | * @author Petr Svenda 12 | */ 13 | public class MPCRunConfig { 14 | 15 | public int targetReaderIndex = 0; 16 | public short numPlayers = 4; 17 | public short thisCardID = 0; 18 | public int numWholeTestRepeats = 1; 19 | public int numSingleOpRepeats = 3; 20 | public Class appletToSimulate; 21 | public short[] perfStops = null; 22 | public short perfStopComplete = -1; 23 | public ArrayList failedPerfTraps = new ArrayList<>(); 24 | public ArrayList perfResultsSubparts = new ArrayList<>(); 25 | public HashMap> perfResultsSubpartsRaw = new HashMap<>(); // hashmap with key being perf trap id, folowed by pair 26 | FileOutputStream perfFile; 27 | public String cardName; 28 | byte[] appletAID = {(byte) 0x00, (byte) 0xA4, (byte) 0x04, (byte) 0x00, (byte) 0x0a, (byte) 0x4d, (byte) 0x50, (byte) 0x43, (byte) 0x41, (byte) 0x70, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x74, (byte) 0x31}; 29 | 30 | public enum CARD_TYPE { 31 | 32 | PHYSICAL, JCOPSIM, JCARDSIMLOCAL, JCARDSIMREMOTE 33 | } 34 | CARD_TYPE testCardType = CARD_TYPE.PHYSICAL; 35 | 36 | public static MPCRunConfig getDefaultConfig() { 37 | MPCRunConfig runCfg = new MPCRunConfig(); 38 | runCfg.targetReaderIndex = 0; 39 | runCfg.numPlayers = 4; 40 | runCfg.thisCardID = 0; 41 | runCfg.numWholeTestRepeats = 1; 42 | runCfg.numSingleOpRepeats = 3; 43 | runCfg.testCardType = CARD_TYPE.PHYSICAL; 44 | runCfg.appletToSimulate = MPCApplet.class; 45 | runCfg.cardName = "unknown"; 46 | 47 | return runCfg; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/SimulatedCard.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import javax.smartcardio.ATR; 4 | import javax.smartcardio.Card; 5 | import javax.smartcardio.CardChannel; 6 | import javax.smartcardio.CardException; 7 | 8 | /** 9 | * 10 | * @author Petr Svenda 11 | */ 12 | public class SimulatedCard extends Card { 13 | 14 | @Override 15 | public ATR getATR() { 16 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 17 | } 18 | 19 | @Override 20 | public String getProtocol() { 21 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 22 | } 23 | 24 | @Override 25 | public CardChannel getBasicChannel() { 26 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 27 | } 28 | 29 | @Override 30 | public CardChannel openLogicalChannel() throws CardException { 31 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 32 | } 33 | 34 | @Override 35 | public void beginExclusive() throws CardException { 36 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 37 | } 38 | 39 | @Override 40 | public void endExclusive() throws CardException { 41 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 42 | } 43 | 44 | @Override 45 | public byte[] transmitControlCommand(int i, byte[] bytes) throws CardException { 46 | throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. 47 | } 48 | 49 | @Override 50 | public void disconnect(boolean bln) throws CardException { 51 | // do nothing 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/SimulatedCardChannelLocal.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import com.licel.jcardsim.io.JavaxSmartCardInterface; 4 | import java.nio.ByteBuffer; 5 | import javacard.framework.AID; 6 | import javax.smartcardio.Card; 7 | import javax.smartcardio.CardChannel; 8 | import javax.smartcardio.CardException; 9 | import javax.smartcardio.CommandAPDU; 10 | import javax.smartcardio.ResponseAPDU; 11 | 12 | /** 13 | * 14 | * @author Petr Svenda 15 | */ 16 | public class SimulatedCardChannelLocal extends CardChannel { 17 | 18 | JavaxSmartCardInterface m_simulator; 19 | SimulatedCard m_card; 20 | AID m_appletAID; 21 | 22 | SimulatedCardChannelLocal(JavaxSmartCardInterface simulator, AID appletAIDRes) { 23 | m_simulator = simulator; 24 | m_card = new SimulatedCard(); 25 | m_appletAID = appletAIDRes; 26 | } 27 | 28 | @Override 29 | public Card getCard() { 30 | return m_card; 31 | } 32 | 33 | @Override 34 | public int getChannelNumber() { 35 | return 0; 36 | } 37 | 38 | @Override 39 | public ResponseAPDU transmit(CommandAPDU apdu) throws CardException { 40 | ResponseAPDU responseAPDU = null; 41 | 42 | try { 43 | responseAPDU = this.m_simulator.transmitCommand(apdu); 44 | // Add delay corresponding to real cards 45 | //int delay = OperationTimes.getCardOperationDelay(apdu); 46 | //Thread.sleep(delay); 47 | } catch (Exception ex) { 48 | ex.printStackTrace(); 49 | } 50 | 51 | return responseAPDU; 52 | } 53 | 54 | @Override 55 | public int transmit(ByteBuffer bb, ByteBuffer bb1) throws CardException { 56 | throw new UnsupportedOperationException("Not supported yet."); 57 | } 58 | 59 | @Override 60 | public void close() throws CardException { 61 | m_simulator.reset(); 62 | m_simulator.deleteApplet(m_appletAID); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/SimulatedMPCPlayer.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import java.math.BigInteger; 4 | import java.security.MessageDigest; 5 | import java.security.NoSuchAlgorithmException; 6 | import java.security.SecureRandom; 7 | 8 | import org.bouncycastle.math.ec.ECPoint; 9 | 10 | import ds.ov2.bignat.Bignat; 11 | import org.bouncycastle.math.ec.ECCurve; 12 | 13 | /** 14 | * 15 | * @author Vasilios Mavroudis and Petr Svenda 16 | */ 17 | class SimulatedMPCPlayer implements MPCPlayer { 18 | 19 | public short playerID; 20 | 21 | ECCurve curve; 22 | //Key Pair 23 | public BigInteger priv_key_BI; 24 | public ECPoint pub_key_EC; 25 | public byte[] pub_key_Hash; 26 | public ECPoint curve_G; 27 | public BigInteger curve_n; 28 | //Signing 29 | public byte[] secret_seed;//{ (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; 30 | public BigInteger k_Bn; 31 | public ECPoint Ri_EC; 32 | public byte[] Ri_Hash; 33 | 34 | //For preloading 35 | public BigInteger k_Bn_pre; 36 | public ECPoint Ri_EC_pre; 37 | public byte[] Ri_Hash_pre; 38 | 39 | public SimulatedMPCPlayer(short playerID, ECPoint G, BigInteger n, ECCurve curve) throws NoSuchAlgorithmException { 40 | this.playerID = playerID; 41 | this.curve_G = G; 42 | this.curve_n = n; 43 | this.curve = curve; 44 | 45 | this.KeyGen(); 46 | SecureRandom random = new SecureRandom(); 47 | secret_seed = new byte[32]; 48 | random.nextBytes(secret_seed); 49 | } 50 | 51 | // 52 | // MPCPlayer methods 53 | // 54 | @Override 55 | public byte[] Gen_Rin(short quorumIndex, short i) throws NoSuchAlgorithmException, Exception { 56 | Bignat counter = Util.makeBignatFromValue(i); 57 | ECPoint Rin = curve_G.multiply(new BigInteger(PRF(counter, this.secret_seed))); 58 | return Rin.getEncoded(false); 59 | } 60 | 61 | @Override 62 | public ECPoint GetPubKey(short quorumIndex) { 63 | return pub_key_EC; 64 | } 65 | 66 | @Override 67 | public short GetPlayerIndex(short quorumIndex) { 68 | return playerID; 69 | } 70 | 71 | @Override 72 | public byte[] GetPubKeyHash(short quorumIndex) { 73 | return pub_key_Hash; 74 | } 75 | 76 | @Override 77 | public ECPoint GetAggregatedPubKey(short quorumIndex) { 78 | return null; 79 | } 80 | 81 | @Override 82 | public BigInteger GetE(short quorumIndex) { 83 | return null; 84 | } 85 | 86 | @Override 87 | public boolean Setup(short quorumIndex, short numPlayers, short thisPlayerID) throws Exception { 88 | // TODO: at the moment, simulated player performs nothing 89 | return true; 90 | } 91 | 92 | @Override 93 | public boolean Reset(short quorumIndex) throws Exception { 94 | // TODO: at the moment, simulated player performs nothing 95 | return true; 96 | } 97 | 98 | @Override 99 | public BigInteger Sign(short quorumIndex, int round, byte[] Rn, byte[] plaintext) throws Exception { 100 | Bignat roundBn = Util.makeBignatFromValue(round); 101 | return Sign(roundBn, Util.ECPointDeSerialization(curve, Rn, 0), plaintext); 102 | } 103 | 104 | @Override 105 | public boolean GenKeyPair(short quorumIndex) throws Exception { 106 | //this.KeyGen(); 107 | return true; 108 | } 109 | 110 | @Override 111 | public boolean RetrievePubKeyHash(short quorumIndex) throws Exception { 112 | return true; 113 | } 114 | 115 | @Override 116 | public boolean StorePubKeyHash(short quorumIndex, short playerIndex, byte[] hash_arr) throws Exception { 117 | // TODO: store pub key hash optionally 118 | return true; 119 | } 120 | 121 | @Override 122 | public byte[] RetrievePubKey(short quorumIndex) throws Exception { 123 | return pub_key_EC.getEncoded(false); 124 | } 125 | 126 | @Override 127 | public boolean StorePubKey(short quorumIndex, short playerIndex, byte[] pub_arr) throws Exception { 128 | return true; 129 | } 130 | 131 | @Override 132 | public boolean RetrieveAggPubKey(short quorumIndex) throws Exception { 133 | return true; 134 | } 135 | 136 | @Override 137 | public byte[] Encrypt(short quorumIndex, byte[] plaintext) throws Exception { 138 | return null; // implement encryption for simulated players 139 | } 140 | 141 | @Override 142 | public byte[] Decrypt(short quorumIndex, byte[] ciphertext) throws Exception { 143 | ECPoint c1 = Util.ECPointDeSerialization(curve, ciphertext, 0); 144 | ECPoint xc1_share = c1.multiply(priv_key_BI); 145 | return xc1_share.getEncoded(false); 146 | } 147 | 148 | @Override 149 | public void disconnect() { 150 | } 151 | 152 | // 153 | // SimulatedMPCPlayer helper methods 154 | // 155 | private final void SetPrivKey(BigInteger privkey) { 156 | priv_key_BI = privkey; 157 | pub_key_EC = curve_G.multiply(priv_key_BI); 158 | } 159 | 160 | private final void KeyGen() throws NoSuchAlgorithmException { 161 | // Keypair + hash 162 | SecureRandom rnd = new SecureRandom(); 163 | priv_key_BI = new BigInteger(256, rnd); 164 | if (MPCTestClient._FIXED_PLAYERS_RNG) { 165 | System.out.println("WARNING: _FIXED_PLAYERS_RNG == true"); 166 | // If true, don't generate random key, but use fixed one instead 167 | priv_key_BI = new BigInteger("B346675518084623BC111CC53FF615B152A3F6D1585278370FA1BA0EA160237E".getBytes()); 168 | } 169 | pub_key_EC = curve_G.multiply(priv_key_BI); 170 | MessageDigest md = MessageDigest.getInstance("SHA-256"); 171 | md.update(pub_key_EC.getEncoded(false)); 172 | pub_key_Hash = md.digest(); 173 | } 174 | 175 | private BigInteger Sign(Bignat i, ECPoint R_EC, byte[] plaintext) throws NoSuchAlgorithmException { 176 | //Gen e (e will be the same in all signature shares) 177 | MessageDigest md = MessageDigest.getInstance("SHA-256"); 178 | //System.out.println("Simulated: Plaintext:" + client.bytesToHex(plaintext)); 179 | //System.out.println("Simulated: Ri,n: " + client.bytesToHex(R_EC.getEncoded(false))); 180 | md.update(plaintext); 181 | md.update(R_EC.getEncoded(false)); // R_EC is the sum of the r_i's 182 | byte[] e = md.digest(); 183 | BigInteger e_BI = new BigInteger(1, e); 184 | 185 | //Gen s_i 186 | this.k_Bn = new BigInteger(PRF(i, secret_seed)); 187 | 188 | BigInteger s_i_BI = this.k_Bn.subtract(e_BI.multiply(this.priv_key_BI)); 189 | s_i_BI = s_i_BI.mod(curve_n); 190 | 191 | /* BUGBUG: I'm cheating a bit here, and use the e returned by the JC. 192 | Btw e is always the same, so it can actually be computed 193 | on the host if this helps with optimizing the applet */ 194 | //System.out.println("Simulated: s: " + client.bytesToHex(s_i_BI.toByteArray())); 195 | //System.out.println("Simulated: e: " + client.bytesToHex(e) + "\n"); 196 | return s_i_BI; 197 | } 198 | 199 | private byte[] PRF(Bignat i, byte[] seed) throws NoSuchAlgorithmException { 200 | MessageDigest md = MessageDigest.getInstance("SHA-256"); 201 | md.reset(); 202 | md.update(i.as_byte_array()); 203 | md.update(seed); 204 | return md.digest(); 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /MPCTestClient/src/mpctestclient/Util.java: -------------------------------------------------------------------------------- 1 | package mpctestclient; 2 | 3 | import ds.ov2.bignat.Bignat; 4 | import java.math.BigInteger; 5 | import java.nio.ByteBuffer; 6 | import java.nio.ByteOrder; 7 | import java.security.KeyPair; 8 | import java.security.KeyPairGenerator; 9 | import java.security.Security; 10 | import javacard.framework.ISO7816; 11 | import javax.smartcardio.ResponseAPDU; 12 | import mpc.Consts; 13 | import org.bouncycastle.jce.ECNamedCurveTable; 14 | import org.bouncycastle.jce.interfaces.ECPublicKey; 15 | import org.bouncycastle.jce.provider.BouncyCastleProvider; 16 | import org.bouncycastle.jce.spec.ECParameterSpec; 17 | import org.bouncycastle.math.ec.ECCurve; 18 | import org.bouncycastle.math.ec.ECPoint; 19 | 20 | /** 21 | * 22 | * @author Vasilios Mavroudis and Petr Svenda 23 | */ 24 | public class Util { 25 | 26 | public static String toHex(byte[] bytes) { 27 | return toHex(bytes, 0, bytes.length); 28 | } 29 | 30 | public static String toHex(byte[] bytes, int offset, int len) { 31 | // StringBuilder buff = new StringBuilder(); 32 | String result = ""; 33 | 34 | for (int i = offset; i < offset + len; i++) { 35 | result += String.format("%02X", bytes[i]); 36 | } 37 | 38 | return result; 39 | } 40 | 41 | public static String bytesToHex(byte[] bytes) { 42 | char[] hexArray = "0123456789ABCDEF".toCharArray(); 43 | char[] hexChars = new char[bytes.length * 2]; 44 | for (int j = 0; j < bytes.length; j++) { 45 | int v = bytes[j] & 0xFF; 46 | hexChars[j * 2] = hexArray[v >>> 4]; 47 | hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 48 | } 49 | return new String(hexChars); 50 | } 51 | 52 | /* Utils */ 53 | public static short getShort(byte[] buffer, int offset) { 54 | return ByteBuffer.wrap(buffer, offset, 2).order(ByteOrder.BIG_ENDIAN).getShort(); 55 | } 56 | 57 | public static short readShort(byte[] data, int offset) { 58 | return (short) (((data[offset] << 8)) | ((data[offset + 1] & 0xff))); 59 | } 60 | 61 | public static byte[] shortToByteArray(int s) { 62 | return new byte[]{(byte) ((s & 0xFF00) >> 8), (byte) (s & 0x00FF)}; 63 | } 64 | 65 | public static int shortToByteArray(short s, byte[] array, int arrayOffset) { 66 | array[arrayOffset] = (byte) ((s & 0xFF00) >> 8); 67 | array[arrayOffset + 1] = (byte) (s & 0x00FF); 68 | return arrayOffset + 2; 69 | } 70 | 71 | public static byte[] joinArray(byte[]... arrays) { 72 | int length = 0; 73 | for (byte[] array : arrays) { 74 | length += array.length; 75 | } 76 | 77 | final byte[] result = new byte[length]; 78 | 79 | int offset = 0; 80 | for (byte[] array : arrays) { 81 | System.arraycopy(array, 0, result, offset, array.length); 82 | offset += array.length; 83 | } 84 | 85 | return result; 86 | } 87 | 88 | public static byte[] trimLeadingZeroes(byte[] array) { 89 | short startOffset = 0; 90 | for (int i = 0; i < array.length; i++) { 91 | if (array[i] != 0) { 92 | break; 93 | } else { 94 | // still zero 95 | startOffset++; 96 | } 97 | } 98 | 99 | byte[] result = new byte[array.length - startOffset]; 100 | System.arraycopy(array, startOffset, result, 0, array.length - startOffset); 101 | return result; 102 | } 103 | 104 | public static byte[] concat(byte[] a, byte[] b) { 105 | int aLen = a.length; 106 | int bLen = b.length; 107 | byte[] c = new byte[aLen + bLen]; 108 | System.arraycopy(a, 0, c, 0, aLen); 109 | System.arraycopy(b, 0, c, aLen, bLen); 110 | return c; 111 | } 112 | 113 | public static byte[] concat(byte[] a, byte[] b, byte[] c) { 114 | byte[] tmp_conc = concat(a, b); 115 | return concat(tmp_conc, c); 116 | 117 | } 118 | 119 | public static ECPoint ECPointDeSerialization(ECCurve curve, byte[] serialized_point, int offset) { 120 | 121 | byte[] x_b = new byte[256 / 8]; 122 | byte[] y_b = new byte[256 / 8]; 123 | 124 | // System.out.println("Serialized Point: " + toHex(serialized_point)); 125 | // src -- This is the source array. 126 | // srcPos -- This is the starting position in the source array. 127 | // dest -- This is the destination array. 128 | // destPos -- This is the starting position in the destination data. 129 | // length -- This is the number of array elements to be copied. 130 | System.arraycopy(serialized_point, offset + 1, x_b, 0, Consts.SHARE_BASIC_SIZE); 131 | BigInteger x = new BigInteger(bytesToHex(x_b), 16); 132 | // System.out.println("X:" + toHex(x_b)); 133 | System.arraycopy(serialized_point, offset + (Consts.SHARE_BASIC_SIZE + 1), y_b, 0, Consts.SHARE_BASIC_SIZE); 134 | BigInteger y = new BigInteger(bytesToHex(y_b), 16); 135 | // System.out.println("Y:" + toHex(y_b)); 136 | 137 | ECPoint point = curve.createPoint(x, y); 138 | 139 | return point; 140 | } 141 | 142 | public static ECPoint randECPoint() throws Exception { 143 | Security.addProvider(new BouncyCastleProvider()); 144 | 145 | ECParameterSpec ecSpec_named = ECNamedCurveTable.getParameterSpec("secp256r1"); // NIST P-256 146 | KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECDSA", "BC"); 147 | kpg.initialize(ecSpec_named); 148 | KeyPair apair = kpg.generateKeyPair(); 149 | ECPublicKey apub = (ECPublicKey) apair.getPublic(); 150 | return apub.getQ(); 151 | } 152 | 153 | public static byte[] IntToBytes(int val) { 154 | byte[] data = new byte[5]; 155 | if (val < 0) { 156 | data[0] = 0x01; 157 | } else { 158 | data[0] = 0x00; 159 | } 160 | 161 | int unsigned = Math.abs(val); 162 | data[1] = (byte) (unsigned >>> 24); 163 | data[2] = (byte) (unsigned >>> 16); 164 | data[3] = (byte) (unsigned >>> 8); 165 | data[4] = (byte) unsigned; 166 | 167 | return data; 168 | } 169 | 170 | public static int BytesToInt(byte[] data) { 171 | int val = (data[1] << 24) 172 | | ((data[2] & 0xFF) << 16) 173 | | ((data[3] & 0xFF) << 8) 174 | | (data[4] & 0xFF); 175 | 176 | if (data[0] == 0x01) { 177 | val = val * -1; 178 | } 179 | 180 | return val; 181 | } 182 | 183 | private static boolean checkSW(ResponseAPDU response) { 184 | if (response.getSW() != (ISO7816.SW_NO_ERROR & 0xffff)) { 185 | System.err.printf("Received error status: %02X.\n", 186 | response.getSW()); 187 | return false; 188 | } 189 | return true; 190 | } 191 | 192 | public static byte[] hexStringToByteArray(String s) { 193 | String sanitized = s.replace(" ", ""); 194 | byte[] b = new byte[sanitized.length() / 2]; 195 | for (int i = 0; i < b.length; i++) { 196 | int index = i * 2; 197 | int v = Integer.parseInt(sanitized.substring(index, index + 2), 16); 198 | b[i] = (byte) v; 199 | } 200 | return b; 201 | } 202 | 203 | public static Bignat makeBignatFromValue(int i) { 204 | Bignat bn = new Bignat((short) 4); 205 | setBignatValue(bn, i); 206 | return bn; 207 | } 208 | 209 | public static Bignat makeBignatFromValue(short i) { 210 | Bignat bn = new Bignat((short) 2); 211 | setBignatValue(bn, i); 212 | return bn; 213 | } 214 | 215 | private static void setBignatValue(Bignat bn, int i) { 216 | //Super bad & ugly way of converting short to Bignat (I've added a proper function in the actual lib) 217 | Bignat one = new Bignat((short) 2); 218 | one.one(); 219 | bn.zero(); 220 | for (int j = 0; j < i; j++) { 221 | bn.add(one); 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /MPCTestClient/test/mpc/BignatTests.java: -------------------------------------------------------------------------------- 1 | package mpc; 2 | 3 | import org.testng.annotations.AfterClass; 4 | import org.testng.annotations.AfterMethod; 5 | import org.testng.annotations.BeforeClass; 6 | import org.testng.annotations.Test; 7 | 8 | 9 | /** 10 | * 11 | * @author Petr Svenda 12 | */ 13 | public class BignatTests { 14 | 15 | // Our constant r is 0xffffffff0000000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 16 | public final static byte[] xe_Bn_testInput1 = {(byte) 0x03, (byte) 0xBD, (byte) 0x28, (byte) 0x6B, (byte) 0x6A, (byte) 0x22, (byte) 0x1F, 17 | (byte) 0x1B, (byte) 0xFC, (byte) 0x08, (byte) 0xC6, (byte) 0xC5, (byte) 0xB0, (byte) 0x3F, (byte) 0x0B, (byte) 0xEA, (byte) 0x6C, 18 | (byte) 0x38, (byte) 0xBE, (byte) 0xBA, (byte) 0xCF, (byte) 0x20, (byte) 0x2A, (byte) 0xAA, (byte) 0xDF, (byte) 0xAC, (byte) 0xA3, 19 | (byte) 0x70, (byte) 0x38, (byte) 0x32, (byte) 0xF8, (byte) 0xCC, (byte) 0xE0, (byte) 0xA8, (byte) 0x70, (byte) 0x88, (byte) 0xE9, 20 | (byte) 0x17, (byte) 0x21, (byte) 0xA3, (byte) 0x4C, (byte) 0x8D, (byte) 0x0B, (byte) 0x97, (byte) 0x11, (byte) 0x98, (byte) 0x02, 21 | (byte) 0x46, (byte) 0x04, (byte) 0x56, (byte) 0x40, (byte) 0xA1, (byte) 0xAE, (byte) 0x34, (byte) 0xC1, (byte) 0xFB, (byte) 0x7D, 22 | (byte) 0xB8, (byte) 0x45, (byte) 0x28, (byte) 0xC6, (byte) 0x1B, (byte) 0xC6, (byte) 0xD0}; 23 | // xe_Bn_testInput1 % r expected output = A63C40BA30E305C0E710DE90B9FCFA67771508E48E7703BB72BD3071B80EB42F 24 | public final static byte[] xe_Bn_testOutput1 = {(byte) 0xA6, (byte) 0x3C, (byte) 0x40, (byte) 0xBA, (byte) 0x30, (byte) 0xE3, (byte) 0x05, 25 | (byte) 0xC0, (byte) 0xE7, (byte) 0x10, (byte) 0xDE, (byte) 0x90, (byte) 0xB9, (byte) 0xFC, (byte) 0xFA, (byte) 0x67, (byte) 0x77, 26 | (byte) 0x15, (byte) 0x08, (byte) 0xE4, (byte) 0x8E, (byte) 0x77, (byte) 0x03, (byte) 0xBB, (byte) 0x72, (byte) 0xBD, (byte) 0x30, 27 | (byte) 0x71, (byte) 0xB8, (byte) 0x0E, (byte) 0xB4, (byte) 0x2F}; 28 | 29 | public final static byte[] xe_Bn_testInput2 = {(byte) 0x72, (byte) 0x44, (byte) 0x21, (byte) 0x42, (byte) 0xe9, (byte) 0xe8, (byte) 0xa7, 30 | (byte) 0x32, (byte) 0x26, (byte) 0xe6, (byte) 0xf9, (byte) 0xb6, (byte) 0xfb, (byte) 0xe5, (byte) 0x09, (byte) 0x2e, (byte) 0x44, 31 | (byte) 0xf4, (byte) 0xdd, (byte) 0x9d, (byte) 0x95, (byte) 0x6d, (byte) 0xe9, (byte) 0xa3, (byte) 0xbe, (byte) 0x25, (byte) 0x61, 32 | (byte) 0x00, (byte) 0x1b, (byte) 0xaf, (byte) 0x04, (byte) 0x84, (byte) 0x55, (byte) 0xcf, (byte) 0xd3, (byte) 0x33, (byte) 0x84, 33 | (byte) 0xbc, (byte) 0xdd, (byte) 0x6b, (byte) 0x0a, (byte) 0x20, (byte) 0x75, (byte) 0x21, (byte) 0xc3, (byte) 0x11, (byte) 0x62, 34 | (byte) 0x4b, (byte) 0x84, (byte) 0xfd, (byte) 0x21, (byte) 0xa1, (byte) 0xfe, (byte) 0xcb, (byte) 0x53, (byte) 0xdb, (byte) 0x15, 35 | (byte) 0x51, (byte) 0xf1, (byte) 0xa1, (byte) 0xa8, (byte) 0x83, (byte) 0x90, (byte) 0x6c}; 36 | // xe_Bn_testInput2 % r expected output = 4C38E7231B781FFFCA11555D137A6F8510C761A761252958531657B612E91718 37 | public final static byte[] xe_Bn_testOutput2 = {(byte) 0x4C, (byte) 0x38, (byte) 0xE7, (byte) 0x23, (byte) 0x1B, (byte) 0x78, (byte) 0x1F, 38 | (byte) 0xFF, (byte) 0xCA, (byte) 0x11, (byte) 0x55, (byte) 0x5D, (byte) 0x13, (byte) 0x7A, (byte) 0x6F, (byte) 0x85, (byte) 0x10, 39 | (byte) 0xC7, (byte) 0x61, (byte) 0xA7, (byte) 0x61, (byte) 0x25, (byte) 0x29, (byte) 0x58, (byte) 0x53, (byte) 0x16, (byte) 0x57, 40 | (byte) 0xB6, (byte) 0x12, (byte) 0xE9, (byte) 0x17, (byte) 0x18}; 41 | 42 | // 2^256 % r where r = 0xffffffff0000000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 43 | public final static byte[] const2kmodR = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 44 | (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x43, (byte) 0x19, (byte) 0x05, (byte) 0x52, (byte) 0x58, (byte) 0xe8, (byte) 0x61, 45 | (byte) 0x7b, (byte) 0x0c, (byte) 0x46, (byte) 0x35, (byte) 0x3d, (byte) 0x03, (byte) 0x9c, (byte) 0xda, (byte) 0xaf}; 46 | 47 | public BignatTests() { 48 | } 49 | 50 | @BeforeClass 51 | public static void setUpClass() throws Exception { 52 | } 53 | 54 | @AfterClass 55 | public static void tearDownClass() throws Exception { 56 | } 57 | 58 | @AfterMethod 59 | public void tearDownMethod() throws Exception { 60 | } 61 | 62 | /* 63 | static byte[] testNonOptimizedModuloBignat(byte[] n, byte[] r) { 64 | Bignat modulo_Bn = new Bignat((short) Consts.RND_SIZE, false); 65 | modulo_Bn.from_byte_array((short) r.length, (short) (0), r, (short) 0); 66 | Bignat xe_Bn = new Bignat(Consts.SHARE_SIZE_64, false); 67 | xe_Bn.from_byte_array((short) n.length, (short) (0), n, (short) 0); 68 | xe_Bn.remainder_divide(modulo_Bn, null); 69 | byte[] result = xe_Bn.as_byte_array(); 70 | // Trim leading zeroes from result array 71 | result = mpcclient.MPCTestClient.trimLeadingZeroes(result); 72 | 73 | return result; 74 | } 75 | 76 | @Test 77 | void testNonOptimizedModuloBignat() { 78 | System.out.format("\n*********** BEGIN: Modulo non-optimized with Bignat ********\n"); 79 | byte[] result = testNonOptimizedModuloBignat(xe_Bn_testInput1, SecP256r1.r); 80 | Assert.assertEquals(result, xe_Bn_testOutput1); 81 | System.out.format("testInput1 mod r = %s\n", mpcclient.MPCTestClient.bytesToHex(result)); 82 | result = testNonOptimizedModuloBignat(xe_Bn_testInput2, SecP256r1.r); 83 | Assert.assertEquals(result, xe_Bn_testOutput2); 84 | System.out.format("testInput2 mod r = %s\n", mpcclient.MPCTestClient.bytesToHex(result)); 85 | 86 | System.out.format("*********** END: Modulo non-optimized with Bignat ********\n"); 87 | } 88 | */ 89 | @Test 90 | void anotherTest() { 91 | assert(false); 92 | } 93 | /* 94 | static byte[] testOptimizedModuloBignat2(byte[] n, byte[] r) { 95 | Bignat modulo_Bn = new Bignat((short) Consts.RND_SIZE, false); 96 | modulo_Bn.from_byte_array((short) r.length, (short) (0), r, (short) 0); 97 | 98 | Bignat n0 = new Bignat(Consts.SHARE_SIZE_64, false); 99 | Bignat n1 = new Bignat(Consts.SHARE_SIZE_32, false); 100 | Bignat const2kmodR_Bn = new Bignat(Consts.SHARE_SIZE_32, false); 101 | 102 | const2kmodR_Bn.set_from_byte_array((short) 0, const2kmodR, (short) 0, (short) const2kmodR.length); 103 | n1.set_from_byte_array((short) 0, xe_Bn_testInput1, (short) 0, (short) ((short) xe_Bn_testInput1.length / 2)); 104 | n0.set_from_byte_array((short) ((short) xe_Bn_testInput1.length / 2), xe_Bn_testInput1, (short) ((short) xe_Bn_testInput1.length / 2), (short) ((short) xe_Bn_testInput1.length / 2)); 105 | Bignat resBn = new Bignat(Consts.SHARE_SIZE_64, false); 106 | 107 | // a1 x (2^k mod r) + a0 108 | resBn.mult(n1, const2kmodR_Bn); 109 | 110 | if (Bignat.add(resBn.as_byte_array(), (short) 0, resBn.size(), n0.as_byte_array(), (short) 0, n0.size())) { 111 | // Carry occured 112 | resBn.as_byte_array()[(short) 0] = 0x01; 113 | } 114 | 115 | System.out.format("a1 x (2^k mod r) + a0 = %s\n", client.client.bytesToHex(resBn.as_byte_array())); 116 | 117 | return client.client.trimLeadingZeroes(resBn.as_byte_array()); 118 | } 119 | 120 | static byte[] testModuloBigInteger(byte[] n, byte[] r) { 121 | // Non-Optimized modulo with Java's BigInteger 122 | BigInteger a2 = new BigInteger(1, n); 123 | BigInteger r2 = new BigInteger(1, r); 124 | a2.negate(); 125 | BigInteger res2 = a2.mod(r2); 126 | System.out.format("a2 mod r2 = %s\n", res2.toString(16)); 127 | // Non-Optimized modulo with Java's BigInteger 128 | 129 | // Optimized but with Java's BigInteger 130 | System.out.format("\n*********** BEGIN: Modulo trick with BigInteger ********\n"); 131 | // n % r = n - ((n * a) >> k) * r 132 | BigInteger testIn1 = new BigInteger(1, n); 133 | // Important: approx_a == mpc.SecP256r1.r but with one additional integer coding the sign 134 | BigInteger a3 = new BigInteger(1, const2kmodR); 135 | //BigInteger r3 = new BigInteger(1, mpc.SecP256r1.r); 136 | 137 | //(n * a) 138 | BigInteger res3 = a3.multiply(testIn1); 139 | System.out.format("n * a = %s\n", res3.toString(16)); 140 | // ((n * a) >> k) 141 | res3 = res3.shiftRight(520); 142 | System.out.format("((n * a) >> k) = %s\n", res3.toString(16)); 143 | // ((n * a) >> k) * r 144 | BigInteger res4 = res3.multiply(r2); 145 | System.out.format("r = %s\n", r2.toString(16)); 146 | System.out.format("((n * a) >> k) * r = %s\n", res4.toString(16)); 147 | // n - ((n * a) >> k) * r 148 | BigInteger res5 = testIn1.subtract(res4); 149 | System.out.format("n - ((n * a) >> k) * r = %s\n", res5.toString(16)); 150 | System.out.format("*********** END: Modulo trick with BigInteger ********\n"); 151 | // Optimized but with Java's BigInteger 152 | 153 | return client.client.trimLeadingZeroes(res5.toByteArray()); 154 | } 155 | 156 | @Test 157 | void testOptimizedModuloBignat2() { 158 | System.out.format("\n*********** BEGIN: Modulo trick with Bignat ********\n"); 159 | 160 | byte[] resultBigInteger = testModuloBigInteger(xe_Bn_testInput2, SecP256r1.r); 161 | Assert.assertEquals(resultBigInteger, xe_Bn_testOutput1); 162 | System.out.format("testInput2 mod r = %s\n", client.client.bytesToHex(resultBigInteger)); 163 | 164 | byte[] result = testOptimizedModuloBignat2(xe_Bn_testInput1, SecP256r1.r); 165 | Assert.assertEquals(result, xe_Bn_testOutput1); 166 | System.out.format("testInput1 mod r = %s\n", client.client.bytesToHex(result)); 167 | 168 | System.out.format("*********** END: Modulo trick with Bignat ********\n"); 169 | } 170 | */ 171 | } 172 | -------------------------------------------------------------------------------- /MPCTestClient/test/mpcclient/MPCProtocolTests.java: -------------------------------------------------------------------------------- 1 | package mpcclient; 2 | 3 | import mpctestclient.MPCTestClient; 4 | import mpctestclient.MPCRunConfig; 5 | import mpc.Consts; 6 | import org.testng.annotations.AfterClass; 7 | import org.testng.annotations.AfterMethod; 8 | import org.testng.annotations.BeforeClass; 9 | import org.testng.annotations.Test; 10 | 11 | 12 | /** 13 | * 14 | * @author Petr Svenda 15 | */ 16 | public class MPCProtocolTests { 17 | 18 | public MPCProtocolTests() { 19 | } 20 | 21 | @BeforeClass 22 | public static void setUpClass() throws Exception { 23 | } 24 | 25 | @AfterClass 26 | public static void tearDownClass() throws Exception { 27 | } 28 | 29 | @AfterMethod 30 | public void tearDownMethod() throws Exception { 31 | } 32 | 33 | @Test 34 | void runMPCProtocol_realCard() throws Exception { 35 | MPCRunConfig runCfg = MPCRunConfig.getDefaultConfig(); 36 | runCfg.targetReaderIndex = 0; 37 | runCfg.numPlayers = 4; 38 | runCfg.thisCardID = 0; 39 | runCfg.numWholeTestRepeats = 1; 40 | runCfg.numSingleOpRepeats = 3; 41 | 42 | // Execute once 43 | MPCTestClient.TestMPCProtocol_v20170920(runCfg); 44 | 45 | // Execute 2x 46 | runCfg.numWholeTestRepeats = 2; 47 | MPCTestClient.TestMPCProtocol_v20170920(runCfg); 48 | 49 | // Execute 10x 50 | runCfg.numWholeTestRepeats = 10; 51 | MPCTestClient.TestMPCProtocol_v20170920(runCfg); 52 | } 53 | 54 | @Test 55 | void runMPCProtocol_2playersOnly_realCard() throws Exception { 56 | MPCRunConfig runCfg = MPCRunConfig.getDefaultConfig(); 57 | runCfg.numPlayers = 2; 58 | runCfg.numSingleOpRepeats = 1; 59 | // Execute once 60 | MPCTestClient.TestMPCProtocol_v20170920(runCfg); 61 | } 62 | 63 | @Test 64 | void runMPCProtocol_maxNumPlayers_realCard() throws Exception { 65 | MPCRunConfig runCfg = MPCRunConfig.getDefaultConfig(); 66 | runCfg.numPlayers = Consts.MAX_NUM_PLAYERS; 67 | // Execute once 68 | mpctestclient.MPCTestClient.TestMPCProtocol_v20170920(runCfg); 69 | } 70 | 71 | 72 | 73 | } 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Myst 2 | ## Secure Multiparty Key Generation, Signature and Decryption JavaCard applet and host application 3 | Cryptographic Hardware from Untrusted Components 4 | 5 | This project implements novel distributed key generation, signature, and decryption with private key distributed among multiple separate entities. 6 | 7 | The research paper and other details are available at https://trojantoleranthardware.github.io/ 8 | 9 | This project is technology demonstrator and requires one or more smartcards with JavaCard platform with remaining players contributing to the protocols simulated in software. 10 |
11 |
12 |

13 | 14 |

15 | 16 | 17 | ## Academic Paper 18 | 19 | If you want get into the math and the technical details, you can find our paper here: https://arxiv.org/pdf/1709.03817.pdf 20 | 21 | If you want to cite this work: 22 | ``` 23 | @inproceedings{mavroudis2017touch, 24 | title={A touch of evil: High-assurance cryptographic hardware from untrusted components}, 25 | author={Mavroudis, Vasilios and Cerulli, Andrea and Svenda, Petr and Cvrcek, Dan and Klinec, Dusan and Danezis, George}, 26 | booktitle={Proceedings of the 2017 ACM SIGSAC Conference on Computer and Communications Security}, 27 | pages={1583--1600}, 28 | year={2017}, 29 | organization={ACM} 30 | } 31 | ``` 32 | 33 |
34 |
35 |
36 |
37 | This work was supported by the European Commission through the H2020-DS-2014-653497 PANORAMIX project and the European Research Council via the European Union’s Seventh Framework Programme (FP/2007-2013) / ERC Grant Agreement n. 307937, and the Czech Science Foundation under project GA16-08565S. 38 | --------------------------------------------------------------------------------