aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2019-07-16 11:44:17 +0200
committerJ08nY2019-07-16 11:44:17 +0200
commite0a4956cafcbb98bdf18c9a25fbf799e4de4a35e (patch)
tree9803e4d0af26639d972bdeda06f935e051db8350
parent46c0a874e494d2311148700058f61b5d8d426f3c (diff)
downloadECTester-e0a4956cafcbb98bdf18c9a25fbf799e4de4a35e.tar.gz
ECTester-e0a4956cafcbb98bdf18c9a25fbf799e4de4a35e.tar.zst
ECTester-e0a4956cafcbb98bdf18c9a25fbf799e4de4a35e.zip
-rw-r--r--README.md110
-rw-r--r--docs/LIBS.md7
-rw-r--r--src/cz/crcs/ectester/applet/AppletBase.java22
-rw-r--r--src/cz/crcs/ectester/applet/ECKeyGenerator.java34
-rw-r--r--src/cz/crcs/ectester/reader/ECTesterReader.java11
-rw-r--r--src/cz/crcs/ectester/reader/command/Command.java11
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/c_timing.c4
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/c_utils.c8
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/mscng.c45
-rw-r--r--util/utils.py18
10 files changed, 186 insertions, 84 deletions
diff --git a/README.md b/README.md
index bdc8cd8..601ba86 100644
--- a/README.md
+++ b/README.md
@@ -103,6 +103,7 @@ See `java -jar ECTesterReader.jar -h`, `java -jar ECTesterReader.jar -ls` and [D
it for later ECDH.
--fixed-public Generate public key only once, keep
it for later ECDH.
+ -kb,--key-builder Allocate KeyPair using KeyBuilder.
-f,--fresh Generate fresh keys (set domain
parameters before every generation).
--time Output better timing values, by
@@ -293,6 +294,9 @@ Currently supported libraries include:
- [libgcrypt](https://www.gnupg.org/related_software/libgcrypt/)
- [Botan](https://botan.randombit.net/)
- [Microsoft CNG](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx)
+ - [Intel Performance Primitives Crypto](https://github.com/intel/ipp-crypto)
+ - [MatrixSSL](https://github.com/matrixssl/matrixssl)
+ - [MbedTLS](https://github.com/ARMmbed/mbedtls)
For more information on ECC libraries see [LIBS](docs/LIBS.md).
@@ -316,24 +320,23 @@ To install, place them in `${java.home}/jre/lib/security/`.
```
usage: ECTesterStandalone.jar [-V] [-h <command>] [-C] [
-(ecdh [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-t <type>] [--key-type <algorithm>] [-n <amount>]
- [-npriv <cat/id>] [--fixed-private] [-npub <cat/id>] [--fixed-public]) |
-(ecdsa [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-npriv <cat/id>] [-npub <cat/id>] [-t <type>]
- [-n <amount>] [-f <file>]) |
-(export [-b <n>] [-o <output_file>] [-t <type>]) |
-(generate [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-n <amount>] [-t <type>]) |
-(list-data [what]) |
-(list-libs) |
-(list-suites) |
-(test [-b <n>] [-nc <cat/id>] [-cn <name>] [-gt <type>] [-kt <type>] [-st <type>] [-f <format>] [--key-type <algorithm>] <test-suite>) ]
-[lib]
+ (ecdh [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-t <type>] [--key-type <algorithm>] [-n <amount>] [-npub <cat/id> | -pub <pubkey>] [--fixed-private] [-npriv <cat/id> | -priv <privkey>] [--fixed-public]) |
+ (ecdsa [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-npriv <cat/id> | -priv <privkey>] [-npub <cat/id> | -pub <pubkey>] [-t <type>] [-n <amount>] [-f <file>]) |
+ (export [-b <n>] [-o <output_file>] [-t <type>]) |
+ (generate [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-n <amount>] [-t <type>]) |
+ (list-data [what]) |
+ (list-libs) |
+ (list-suites) |
+ (list-types) |
+ (test [-b <n>] [-nc <cat/id>] [-cn <name>] [-gt <type>] [-kt <type>] [-st <type>] [-f <format>] [--key-type <algorithm>] <test-suite>)
+] [lib]
- -V,--version Print version info.
- -h,--help <command> Print help(about <command>).
- -C,--color Print stuff with color, requires ANSI terminal.
- [lib] What library to use.
+ -V,--version Print version info.
+ -h,--help <command> Print help(about <command>).
+ -C,--color Print stuff with color, requires ANSI terminal.
+ [lib] What library to use.
- ecdh: | Perform EC based KeyAgreement. |
+ ecdh: | Perform EC based KeyAgreement. |
-b,--bits <n> What size of curve to use.
-nc,--named-curve <cat/id> Use a named curve, from CurveDB:
<cat/id>
@@ -343,17 +346,18 @@ usage: ECTesterStandalone.jar [-V] [-h <command>] [-C] [
-t,--type <type> Set KeyAgreement object [type].
--key-type <algorithm> Set the key [algorithm] for which the
key should be derived in
- KeyAgreements with KDF. Default is
- "AES".
+ KeyAgreements with KDF. Default is "AES".
-n,--amount <amount> Do ECDH [amount] times.
- -npriv,--named-private <cat/id> Use a named private key, from
- CurveDB: <cat/id>
- --fixed-private Perform ECDH with fixed private key.
-npub,--named-public <cat/id> Use a named public key, from CurveDB:
<cat/id>
+ -pub,--public <pubkey> Use a given public key from file.
+ --fixed-private Perform ECDH with fixed private key.
+ -npriv,--named-private <cat/id> Use a named private key, from
+ CurveDB: <cat/id>
+ -priv,--private <privkey> Use a given private key from file.
--fixed-public Perform ECDH with fixed public key.
- ecdsa: | Perform EC based Signature. |
+ ecdsa: | Perform EC based Signature. |
-b,--bits <n> What size of curve to use.
-nc,--named-curve <cat/id> Use a named curve, from CurveDB:
<cat/id>
@@ -362,46 +366,50 @@ usage: ECTesterStandalone.jar [-V] [-h <command>] [-C] [
-o,--output <output_file> Output into file <output_file>.
-npriv,--named-private <cat/id> Use a named private key, from
CurveDB: <cat/id>
+ -priv,--private <privkey> Use a given private key from file.
-npub,--named-public <cat/id> Use a named public key, from CurveDB:
<cat/id>
+ -pub,--public <pubkey> Use a given public key from file.
-t,--type <type> Set Signature object [type].
-n,--amount <amount> Do ECDSA [amount] times.
-f,--file <file> Input [file] to sign.
- export: | Export default curve parameters. |
- -b,--bits <n> What size of curve to use.
- -o,--output <output_file> Output into file <output_file>.
- -t,--type <type> Set KeyPair object [type].
+ export: | Export default curve parameters. |
+ -b,--bits <n> What size of curve to use.
+ -o,--output <output_file> Output into file <output_file>.
+ -t,--type <type> Set KeyPair object [type].
- generate: | Generate EC keypairs. |
- -b,--bits <n> What size of curve to use.
- -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id>
- -cn,--curve-name <name> Use a named curve, search from curves
- supported by the library: <name>
- -o,--output <output_file> Output into file <output_file>.
- -n,--amount <amount> Generate [amount] of EC keys.
- -t,--type <type> Set KeyPairGenerator object [type].
+ generate: | Generate EC keypairs. |
+ -b,--bits <n> What size of curve to use.
+ -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id>
+ -cn,--curve-name <name> Use a named curve, search from curves
+ supported by the library: <name>
+ -o,--output <output_file> Output into file <output_file>.
+ -n,--amount <amount> Generate [amount] of EC keys.
+ -t,--type <type> Set KeyPairGenerator object [type].
- list-data: | List/show contained EC domain parameters/keys. |
+ list-data: | List/show contained EC domain parameters/keys. |
[what] what to list.
- list-libs: | List supported libraries. |
+ list-libs: | List supported libraries. |
+
+ list-suites: | List supported test suites. |
- list-suites: | List supported test suites. |
+ list-types: | List KeyPairGenerator, KeyAgreement and Signature types. |
- test: | Test a library. |
- -b,--bits <n> What size of curve to use.
- -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id>
- -cn,--curve-name <name> Use a named curve, search from curves
- supported by the library: <name>
- -gt,--kpg-type <type> Set the KeyPairGenerator object [type].
- -kt,--ka-type <type> Set the KeyAgreement object [type].
- -st,--sig-type <type> Set the Signature object [type].
- -f,--format <format> Set the output format, one of
- text,yaml,xml.
- --key-type <algorithm> Set the key [algorithm] for which the key
- should be derived in KeyAgreements with
- KDF. Default is "AES".
- <test-suite> The test suite to run.
+ test: | Test a library. |
+ -b,--bits <n> What size of curve to use.
+ -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id>
+ -cn,--curve-name <name> Use a named curve, search from curves
+ supported by the library: <name>
+ -gt,--kpg-type <type> Set the KeyPairGenerator object [type].
+ -kt,--ka-type <type> Set the KeyAgreement object [type].
+ -st,--sig-type <type> Set the Signature object [type].
+ -f,--format <format> Set the output format, one of
+ text,yaml,xml.
+ --key-type <algorithm> Set the key [algorithm] for which the key
+ should be derived in KeyAgreements with
+ KDF. Default is "AES".
+ <test-suite> The test suite to run.
```
diff --git a/docs/LIBS.md b/docs/LIBS.md
index ab6779f..0987656 100644
--- a/docs/LIBS.md
+++ b/docs/LIBS.md
@@ -5,6 +5,8 @@ Popular libraries with at least some ECC support, that ECTester does not yet sup
- [NSS](https://hg.mozilla.org/projects/nss)
- [LibreSSL](https://www.libressl.org/)
- [Nettle](http://www.lysator.liu.se/~nisse/nettle/)
+ - [BearSSL](https://bearssl.org/)
+ - [cryptlib](https://www.cryptlib.com/)
- [OpenSSL (FIPS mode)](https://www.openssl.org/docs/fipsnotes.html)
- [Microsoft .NET crypto](https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model)
- [Linux kernel](https://kernel.org), test via [libkcapi](http://chronox.de/libkcapi.html)
@@ -119,6 +121,11 @@ ninja
- Uses comb method for short Weierstrass curves, using (randomized) Jacobian coordinates.
- <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2>
- Uses Montgomery ladder with xz coordinates for Montgomery curves.
+ - [MatrixSSL](https://github.com/matrixssl/matrixssl)
+ - C
+ - Only supports prime field curves.
+ - Uses 4 bit sliding window.
+ - Uses projective coordinates.
- [Intel Performance Primitives](https://software.intel.com/en-us/ipp-crypto-reference-2019)
- C
- Only supports prime field curves.
diff --git a/src/cz/crcs/ectester/applet/AppletBase.java b/src/cz/crcs/ectester/applet/AppletBase.java
index 4669352..dc0f50d 100644
--- a/src/cz/crcs/ectester/applet/AppletBase.java
+++ b/src/cz/crcs/ectester/applet/AppletBase.java
@@ -39,6 +39,8 @@ public abstract class AppletBase extends Applet {
public static final byte KEYPAIR_LOCAL = (byte) 0x01;
public static final byte KEYPAIR_REMOTE = (byte) 0x02;
public static final byte KEYPAIR_BOTH = KEYPAIR_LOCAL | KEYPAIR_REMOTE;
+ public static final byte BUILD_KEYPAIR = (byte) 0x00;
+ public static final byte BUILD_KEYBUILDER = (byte) 0x01;
public static final byte EXPORT_TRUE = (byte) 0xff;
public static final byte EXPORT_FALSE = (byte) 0x00;
public static final byte MODE_NORMAL = (byte) 0xaa;
@@ -352,17 +354,18 @@ public abstract class AppletBase extends Applet {
* returns allocate SWs
*
* @param apdu P1 = byte keyPair (KEYPAIR_* | ...)
- * P2 =
+ * P2 = byte build
* DATA = short keyLength
* byte keyClass
* @return length of response
*/
private short insAllocate(APDU apdu) {
byte keyPair = apduArray[ISO7816.OFFSET_P1];
+ byte build = apduArray[ISO7816.OFFSET_P2];
short keyLength = Util.getShort(apduArray, cdata);
byte keyClass = apduArray[(short) (cdata + 2)];
- return allocate(keyPair, keyLength, keyClass, apdu.getBuffer(), (short) 0);
+ return allocate(keyPair, build, keyLength, keyClass, apdu.getBuffer(), (short) 0);
}
/**
@@ -657,22 +660,31 @@ public abstract class AppletBase extends Applet {
/**
* @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...)
+ * @param build whether to use KeyBuilder or Keypair alloc
* @param keyLength key length to set
* @param keyClass key class to allocate
* @param outBuffer buffer to write sw to
* @param outOffset offset into buffer
* @return length of data written to the buffer
*/
- private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] outBuffer, short outOffset) {
+ private short allocate(byte keyPair, byte build, short keyLength, byte keyClass, byte[] outBuffer, short outOffset) {
short length = 0;
if ((keyPair & KEYPAIR_LOCAL) != 0) {
- localKeypair = keyGenerator.allocatePair(keyClass, keyLength);
+ if (build == BUILD_KEYPAIR) {
+ localKeypair = keyGenerator.allocatePair(keyClass, keyLength);
+ } else {
+ localKeypair = keyGenerator.constructPair(keyClass, keyLength);
+ }
Util.setShort(outBuffer, outOffset, keyGenerator.getSW());
length += 2;
}
if ((keyPair & KEYPAIR_REMOTE) != 0) {
- remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength);
+ if (build == BUILD_KEYPAIR) {
+ remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength);
+ } else {
+ remoteKeypair = keyGenerator.constructPair(keyClass, keyLength);
+ }
Util.setShort(outBuffer, (short) (outOffset + length), keyGenerator.getSW());
length += 2;
}
diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java
index 30910ca..601654a 100644
--- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java
+++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java
@@ -4,9 +4,7 @@ import javacard.framework.CardRuntimeException;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
-import javacard.security.ECPrivateKey;
-import javacard.security.ECPublicKey;
-import javacard.security.KeyPair;
+import javacard.security.*;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -42,6 +40,36 @@ public class ECKeyGenerator {
}
/**
+ * @param keyClass
+ * @param keyLength
+ * @return
+ */
+ public KeyPair constructPair(byte keyClass, short keyLength) {
+ sw = ISO7816.SW_NO_ERROR;
+ KeyPair ecKeyPair = null;
+ byte privKeyType;
+ byte pubKeyType;
+ if (keyClass == KeyPair.ALG_EC_FP) {
+ privKeyType = KeyBuilder.TYPE_EC_FP_PRIVATE;
+ pubKeyType = KeyBuilder.TYPE_EC_FP_PUBLIC;
+ } else {
+ privKeyType = KeyBuilder.TYPE_EC_F2M_PRIVATE;
+ pubKeyType = KeyBuilder.TYPE_EC_F2M_PUBLIC;
+ }
+ try {
+ if (!dryRun) {
+ ECPrivateKey privateKey = (ECPrivateKey) KeyBuilder.buildKey(privKeyType, keyLength, false);
+ ECPublicKey publicKey = (ECPublicKey) KeyBuilder.buildKey(pubKeyType, keyLength, false);
+
+ ecKeyPair = new KeyPair(publicKey, privateKey);
+ }
+ } catch (CardRuntimeException ce) {
+ sw = ce.getReason();
+ }
+ return ecKeyPair;
+ }
+
+ /**
* @param keypair
* @param key
* @return
diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java
index 6e34f6a..07bdb2f 100644
--- a/src/cz/crcs/ectester/reader/ECTesterReader.java
+++ b/src/cz/crcs/ectester/reader/ECTesterReader.java
@@ -327,6 +327,7 @@ public class ECTesterReader {
opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build());
opts.addOption(Option.builder().longOpt("format").desc("Output format to use. One of: text,yml,xml.").hasArg().argName("format").build());
+ opts.addOption(Option.builder("kb").longOpt("key-builder").desc("Allocate KeyPair using KeyBuilder.").build());
opts.addOption(Option.builder().longOpt("fixed").desc("Generate key(s) only once, keep them for later operations.").build());
opts.addOption(Option.builder().longOpt("fixed-private").desc("Generate private key only once, keep it for later ECDH.").build());
opts.addOption(Option.builder().longOpt("fixed-public").desc("Generate public key only once, keep it for later ECDH.").build());
@@ -394,7 +395,7 @@ public class ECTesterReader {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> sent = new LinkedList<>();
- sent.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send());
+ sent.add(new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send());
//sent.add(new Command.Clear(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send());
sent.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send());
@@ -444,7 +445,7 @@ public class ECTesterReader {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
Command curve = Command.prepareCurve(cardManager, cfg, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass);
- Response allocate = new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send();
+ Response allocate = new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send();
respWriter.outputResponse(allocate);
OutputStreamWriter keysFile = FileUtil.openFiles(cfg.outputs);
@@ -577,7 +578,7 @@ public class ECTesterReader {
Command curve = Command.prepareCurve(cardManager, cfg, ECTesterApplet.KEYPAIR_BOTH, cfg.bits, keyClass);
List<Response> prepare = new LinkedList<>();
prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.ECKAType).send()); // Prepare KeyAgreement or required type
- prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, cfg.bits, keyClass).send());
+ prepare.add(new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_BOTH, cfg.bits, keyClass).send());
if (curve != null)
prepare.add(curve.send());
@@ -703,7 +704,7 @@ public class ECTesterReader {
byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M;
List<Response> prepare = new LinkedList<>();
prepare.add(new Command.AllocateSignature(cardManager, cfg.ECDSAType).send());
- prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send());
+ prepare.add(new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send());
Command curve = Command.prepareCurve(cardManager, cfg, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass);
if (curve != null)
prepare.add(curve.send());
@@ -835,6 +836,7 @@ public class ECTesterReader {
public boolean fixedKey = false;
public boolean fixedPrivate = false;
public boolean fixedPublic = false;
+ public byte keyBuilder;
public String log;
@@ -894,6 +896,7 @@ public class ECTesterReader {
fixedKey = cli.hasOption("fixed");
fixedPrivate = cli.hasOption("fixed-private");
fixedPublic = cli.hasOption("fixed-public");
+ keyBuilder = cli.hasOption("key-builder") ? ECTesterApplet.BUILD_KEYBUILDER : ECTesterApplet.BUILD_KEYPAIR;
if (cli.hasOption("log")) {
log = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000));
diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java
index 1789451..cd015df 100644
--- a/src/cz/crcs/ectester/reader/command/Command.java
+++ b/src/cz/crcs/ectester/reader/command/Command.java
@@ -255,6 +255,7 @@ public abstract class Command implements Cloneable {
*/
public static class Allocate extends Command {
private byte keyPair;
+ private byte build;
private short keyLength;
private byte keyClass;
@@ -263,18 +264,24 @@ public abstract class Command implements Cloneable {
*
* @param cardManager cardManager to send APDU through
* @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...)
+ * @param build whether to use KeyBuilder or Keypair alloc
* @param keyLength key length to set
* @param keyClass key class to allocate
*/
- public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) {
+ public Allocate(CardMngr cardManager, byte keyPair, byte build, short keyLength, byte keyClass) {
super(cardManager);
this.keyPair = keyPair;
+ this.build = build;
this.keyLength = keyLength;
this.keyClass = keyClass;
byte[] data = new byte[]{0, 0, keyClass};
ByteUtil.setShort(data, 0, keyLength);
- this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data);
+ this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, build, data);
+ }
+
+ public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) {
+ this(cardManager, keyPair, ECTesterApplet.BUILD_KEYPAIR, keyLength, keyClass);
}
@Override
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c b/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c
index a6ffc7e..941cee6 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c
@@ -1,5 +1,9 @@
#include "c_timing.h"
+#if __linux || __posix
+#include<unistd.h>
+#endif
+
#if _POSIX_TIMERS > 0
#include <time.h>
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
index a5bc14d..46286fd 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c
@@ -3,6 +3,10 @@
#include <string.h>
#include <stdlib.h>
+#if defined(__WIN32__) || defined(_MSC_VER)
+#include <windows.h>
+#endif
+
jclass ec_parameter_spec_class;
jclass ecgen_parameter_spec_class;
jclass secret_key_spec_class;
@@ -228,7 +232,11 @@ char *biginteger_to_hex(JNIEnv *env, jobject big, jint bytes) {
jstring big_string = (*env)->CallObjectMethod(env, big, to_string, (jint) 16);
jsize len = (*env)->GetStringUTFLength(env, big_string);
+#if defined(__WIN32__) || defined(_MSC_VER)
+ char *raw_string = _alloca(len);
+#else
char raw_string[len];
+#endif
(*env)->GetStringUTFRegion(env, big_string, 0, len, raw_string);
char *result = calloc(bytes, 2);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
index 2b38860..7f3ff5d 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c
@@ -1,12 +1,10 @@
-#include <bcrypt.h>
#include <windows.h>
+#include <bcrypt.h>
#include "native.h"
#include "c_timing.h"
#include "c_utils.h"
-#include <stdio.h>
-
// BCRYPT and NT things.
#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#define NT_FAILURE(status) !NT_SUCCESS(status)
@@ -17,8 +15,7 @@
typedef struct {
ULONG dwVersion; // Version of the structure
ECC_CURVE_TYPE_ENUM dwCurveType; // Supported curve types.
- ECC_CURVE_ALG_ID_ENUM
- dwCurveGenerationAlgId; // For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
+ ECC_CURVE_ALG_ID_ENUM dwCurveGenerationAlgId; // For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
ULONG cbFieldLength; // Byte length of the fields P, A, B, X, Y.
ULONG cbSubgroupOrder; // Byte length of the subgroup.
ULONG cbCofactor; // Byte length of cofactor of G in E.
@@ -1203,6 +1200,12 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
return JNI_FALSE;
}
(*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
+
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint ord_bits = (*env)->CallIntMethod(env, n, get_bitlength);
+ jint ord_bytes = (ord_bits + 7) / 8;
jint sig_len = (*env)->GetArrayLength(env, sig);
jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
@@ -1224,20 +1227,24 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
jbyte *r_cpy = r;
jbyte *s_cpy = s;
- if (rlen > slen) {
- r_cpy += rlen - slen;
- rlen = slen;
- } else if (slen > rlen) {
- s_cpy += slen - rlen;
- slen = rlen;
- } else {
- if (r[0] == 0 && s[0] == 0) {
- r_cpy++;
- s_cpy++;
- rlen--;
- slen--;
- }
- }
+ if (rlen > ord_bytes) {
+ r_cpy += ord_bytes - rlen;
+ }
+ if (slen > ord_bytes) {
+ s_cpy += ord_bytes - slen;
+ }
+ if (rlen < ord_bytes) {
+ r_cpy = _alloca(ord_bytes);
+ memset(r_cpy, 0, ord_bytes);
+ memcpy(r_cpy, r + (ord_bytes - rlen), ord_bytes);
+ }
+ if (slen < ord_bytes) {
+ s_cpy = _alloca(ord_bytes);
+ memset(s_cpy, 0, ord_bytes);
+ memcpy(s_cpy, s + (ord_bytes - slen), ord_bytes);
+ }
+ rlen = ord_bytes;
+ slen = ord_bytes;
UCHAR *sig_full = calloc(rlen + slen, 1);
memcpy(sig_full, r_cpy, rlen);
diff --git a/util/utils.py b/util/utils.py
index 670e7c2..1c620ef 100644
--- a/util/utils.py
+++ b/util/utils.py
@@ -69,3 +69,21 @@ def plot_hist(axes, data, xlabel=None, log=False, avg=True, median=True, bins=No
def miller_correction(entropy, samples, bins):
return entropy + (bins - 1)/(2*samples)
+
+
+def egcd(a, b):
+ if a == 0:
+ return b, 0, 1
+ else:
+ g, y, x = egcd(b % a, a)
+ return g, x - (b // a) * y, y
+
+
+def mod_inv(a, p):
+ if a < 0:
+ return p - mod_inv(-a, p)
+ g, x, y = egcd(a, p)
+ if g != 1:
+ raise ArithmeticError("Modular inverse does not exist")
+ else:
+ return x % p