Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Code quality, unit tests, exceptions, scopes, etc. #51

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.wultra.security.pqc.sike;
kasahiti marked this conversation as resolved.
Show resolved Hide resolved

/**
* Constants class that holds all project's constants
*
* @author Kastriot Sahiti, [email protected]
*/
public class Constants {

private Constants() {

}

public static class Exceptions {
public static final String INVALID_PUBLIC_KEY = "Invalid public key";
public static final String INVALID_PRIVATE_KEY = "Invalid private key";
public static final String INVALID_C0 = "Invalid parameter C0";
public static final String INVALID_C1 = "Invalid parameter C1";
public static final String INVALID_MESSAGE = "Invalid message";
public static final String INVALID_PARTY = "Invalid party";
public static final String INVALID_PRIVATE_KEY_DECAPSULATION = "Private key cannot be used for decapsulation";
public static final String INVALID_POINT_COORDINATE = "Invalid point coordinate";
public static final String INVALID_SIKE_PARAM = "Invalid parameter sikeParam";
public static final String INVALID_BYTES_PARAM = "Invalid parameter bytes";
public static final String INVALID_IMPLEMENTATION_TYPE = "Invalid implementation type";
public static final String INVALID_SECRET = "Invalid secret";
public static final String INVALID_OCTET_STRING = "Invalid octet string";

public static final String NOT_IMPLEMENTED = "Not implemented yet";
public static final String UNSUPPORTED_IMPLEMENTATION = "Unsupported implementation type";
public static final String NULL_ENCRYPTED_MESSAGE = "Encrypted message is null";

public static final String NEGATIVE_EXPONENT = "Negative exponent";
public static final String NUMBER_TOO_LARGE = "Number is too large";
public static final String NEGATIVE_NUMBER = "Number is negative";

private Exceptions() {

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.crypto;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.model.ImplementationType;
import com.wultra.security.pqc.sike.model.MontgomeryCurve;
import com.wultra.security.pqc.sike.model.Party;
Expand Down Expand Up @@ -88,7 +89,7 @@ public PrivateKey generatePrivateKey(Party party) throws GeneralSecurityExceptio
*/
public PublicKey derivePublicKey(Party party, PrivateKey privateKey) throws InvalidKeyException {
if (!(privateKey instanceof SidhPrivateKey)) {
throw new InvalidKeyException("Invalid private key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PRIVATE_KEY);
}
SidhPrivateKey priv = (SidhPrivateKey) privateKey;
MontgomeryCurve curve;
Expand All @@ -97,14 +98,14 @@ public PublicKey derivePublicKey(Party party, PrivateKey privateKey) throws Inva
} else if (sikeParam.getImplementationType() == ImplementationType.OPTIMIZED) {
curve = new MontgomeryCurve(sikeParam, sikeParam.getA());
} else {
throw new InvalidParameterException("Unsupported implementation type");
throw new InvalidParameterException(Constants.Exceptions.UNSUPPORTED_IMPLEMENTATION);
}
if (party == Party.ALICE) {
return sikeParam.getIsogeny().isoGen2(curve, priv);
} else if (party == Party.BOB) {
return sikeParam.getIsogeny().isoGen3(curve, priv);
}
throw new InvalidParameterException("Invalid party");
throw new InvalidParameterException(Constants.Exceptions.INVALID_PARTY);
}

/**
Expand All @@ -128,7 +129,7 @@ private BigInteger generateRandomKey(SikeParam sikeParam, Party party) throws Ge
randomBytes[randomBytes.length - 1] &= sikeParam.getMaskB();
return ByteEncoding.fromByteArray(randomBytes);
}
throw new InvalidParameterException("Invalid party");
throw new InvalidParameterException(Constants.Exceptions.INVALID_PARTY);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
*/
public class RandomGenerator {

private SecureRandom secureRandom;
private volatile SecureRandom secureRandom;

/**
* Default random generator constructor.
Expand All @@ -50,20 +50,23 @@ public RandomGenerator(SecureRandom secureRandom) {
* @throws NoSuchProviderException Thrown in case Bouncy Castle provider is not available.
* @throws NoSuchAlgorithmException Thrown in case random generator algorithm is not available.
*/
public byte[] generateRandomBytes(int length) throws NoSuchProviderException, NoSuchAlgorithmException {
if (secureRandom == null) {
public synchronized byte[] generateRandomBytes(int length) throws NoSuchProviderException, NoSuchAlgorithmException {
kasahiti marked this conversation as resolved.
Show resolved Hide resolved
SecureRandom localSecureRandom = secureRandom;

if (localSecureRandom == null) {
synchronized (RandomGenerator.class) {
if (secureRandom == null) {
localSecureRandom = secureRandom;
if (localSecureRandom == null)
// Use SecureRandom implementation from Bouncy Castle library, it is slower,
// however it reseeds periodically and it is quantum safe. The initialization is lazy
// to allow dynamic Bouncy Castle provider initialization and to allow instantiation
// of this class in fields.
secureRandom = SecureRandom.getInstance("DEFAULT", "BC");
}
secureRandom = localSecureRandom = SecureRandom.getInstance("DEFAULT", "BC");
}
}

byte[] randomBytes = new byte[length];
secureRandom.nextBytes(randomBytes);
localSecureRandom.nextBytes(randomBytes);
return randomBytes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.crypto;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.math.api.Fp2Element;
import com.wultra.security.pqc.sike.model.Party;
import com.wultra.security.pqc.sike.model.SidhPrivateKey;
Expand Down Expand Up @@ -51,10 +52,10 @@ public Sidh(SikeParam sikeParam) {
*/
public Fp2Element generateSharedSecret(Party party, PrivateKey privateKey, PublicKey publicKey) throws GeneralSecurityException {
if (!(privateKey instanceof SidhPrivateKey)) {
throw new InvalidKeyException("Invalid private key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PRIVATE_KEY);
}
if (!(publicKey instanceof SidhPublicKey)) {
throw new InvalidKeyException("Invalid public key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PUBLIC_KEY);
}
SidhPrivateKey priv = (SidhPrivateKey) privateKey;
SidhPublicKey pub = (SidhPublicKey) publicKey;
Expand All @@ -64,6 +65,6 @@ public Fp2Element generateSharedSecret(Party party, PrivateKey privateKey, Publi
if (party == Party.BOB) {
return sikeParam.getIsogeny().isoEx3(sikeParam, priv.getKey(), pub.getPx(), pub.getQx(), pub.getRx());
}
throw new InvalidParameterException("Invalid party");
throw new InvalidParameterException(Constants.Exceptions.INVALID_PARTY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.crypto;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.math.api.Fp2Element;
import com.wultra.security.pqc.sike.model.*;
import com.wultra.security.pqc.sike.param.SikeParam;
Expand Down Expand Up @@ -68,7 +69,7 @@ public Sike(SikeParam sikeParam, SecureRandom secureRandom) {
*/
public EncapsulationResult encapsulate(PublicKey pk3) throws GeneralSecurityException {
if (!(pk3 instanceof SidhPublicKey)) {
throw new InvalidKeyException("Invalid public key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PUBLIC_KEY);
}
byte[] m = randomGenerator.generateRandomBytes(sikeParam.getMessageBytes());
byte[] r = generateR(m, pk3.getEncoded());
Expand All @@ -88,23 +89,23 @@ public EncapsulationResult encapsulate(PublicKey pk3) throws GeneralSecurityExce
*/
public byte[] decapsulate(PrivateKey sk3, PublicKey pk3, EncryptedMessage encrypted) throws GeneralSecurityException {
if (!(sk3 instanceof SidhPrivateKey)) {
throw new InvalidKeyException("Invalid private key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PRIVATE_KEY);
}
if (!(pk3 instanceof SidhPublicKey)) {
throw new InvalidKeyException("Invalid public key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PUBLIC_KEY);
}
if (encrypted == null) {
throw new InvalidParameterException("Encrypted message is null");
throw new InvalidParameterException(Constants.Exceptions.NULL_ENCRYPTED_MESSAGE);
}
if (encrypted.getC0() == null) {
throw new InvalidParameterException("Invalid parameter c0");
throw new InvalidParameterException(Constants.Exceptions.INVALID_C0);
}
if (encrypted.getC1() == null) {
throw new InvalidParameterException("Invalid parameter c1");
throw new InvalidParameterException(Constants.Exceptions.INVALID_C1);
}
SidhPrivateKey priv3 = (SidhPrivateKey) sk3;
if (priv3.getS() == null) {
throw new InvalidParameterException("Private key cannot be used for decapsulation");
throw new InvalidParameterException(Constants.Exceptions.INVALID_PRIVATE_KEY_DECAPSULATION);
}
byte[] m = decrypt(sk3, encrypted);
byte[] r = generateR(m, pk3.getEncoded());
Expand Down Expand Up @@ -143,10 +144,10 @@ public EncryptedMessage encrypt(PublicKey pk3, byte[] m) throws GeneralSecurityE
*/
private EncryptedMessage encrypt(PublicKey pk3, byte[] m, byte[] r) throws GeneralSecurityException {
if (!(pk3 instanceof SidhPublicKey)) {
throw new InvalidKeyException("Invalid public key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PUBLIC_KEY);
}
if (m == null || m.length != sikeParam.getMessageBytes()) {
throw new InvalidParameterException("Invalid message");
throw new InvalidParameterException(Constants.Exceptions.INVALID_MESSAGE);
}
PrivateKey sk2;
if (r == null) {
Expand Down Expand Up @@ -177,18 +178,18 @@ private EncryptedMessage encrypt(PublicKey pk3, byte[] m, byte[] r) throws Gener
*/
public byte[] decrypt(PrivateKey sk3, EncryptedMessage encrypted) throws GeneralSecurityException {
if (!(sk3 instanceof SidhPrivateKey)) {
throw new InvalidKeyException("Invalid private key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PRIVATE_KEY);
}
if (encrypted == null) {
throw new InvalidParameterException("Encrypted message is null");
throw new InvalidParameterException(Constants.Exceptions.NULL_ENCRYPTED_MESSAGE);
}
PublicKey c0 = encrypted.getC0();
if (!(c0 instanceof SidhPublicKey)) {
throw new InvalidKeyException("Invalid public key");
throw new InvalidKeyException(Constants.Exceptions.INVALID_PUBLIC_KEY);
}
byte[] c1 = encrypted.getC1();
if (c1 == null) {
throw new InvalidParameterException("Invalid parameter c1");
throw new InvalidParameterException(Constants.Exceptions.INVALID_C1);
}
Fp2Element j = sidh.generateSharedSecret(Party.BOB, sk3, c0);
byte[] h = Sha3.shake256(j.getEncoded(), sikeParam.getMessageBytes());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.math.optimized;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.math.api.Fp2Element;
import com.wultra.security.pqc.sike.math.api.Fp2Point;

Expand Down Expand Up @@ -52,7 +53,7 @@ public Fp2Element getX() {
*/
@Override
public Fp2Element getY() {
throw new InvalidParameterException("Invalid point coordinate");
throw new InvalidParameterException(Constants.Exceptions.INVALID_POINT_COORDINATE);
}

@Override
Expand Down Expand Up @@ -87,12 +88,12 @@ public Fp2Point inverse() {

@Override
public Fp2Point negate() {
throw new RuntimeException("Not implemented yet");
throw new UnsupportedOperationException(Constants.Exceptions.NOT_IMPLEMENTED);
}

@Override
public boolean isInfinite() {
throw new RuntimeException("Not implemented yet");
throw new UnsupportedOperationException(Constants.Exceptions.NOT_IMPLEMENTED);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.math.optimized.fp;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.math.api.Fp2Element;
import com.wultra.security.pqc.sike.math.api.FpElement;
import com.wultra.security.pqc.sike.param.SikeParam;
Expand Down Expand Up @@ -83,10 +84,9 @@ public FpElement getX1() {
*/
public Fp2Element add(Fp2Element y) {
// y = (x0 + i*x1) + (y0 + i*y1) = x0 + y0 + i*(x1 + y1)
FpElement r, i;
FpElement r = x0.add(y.getX0());
petrdvorak marked this conversation as resolved.
Show resolved Hide resolved
FpElement i = x1.add(y.getX1());

r = x0.add(y.getX0());
i = x1.add(y.getX1());
return new Fp2ElementOpti(sikeParam, r, i);
}

Expand All @@ -97,10 +97,9 @@ public Fp2Element add(Fp2Element y) {
*/
public Fp2Element subtract(Fp2Element y) {
// y = (x0 + i*x1) - (y0 + i*y1) = x0 - y0 + i*(x1 - y1)
FpElement r, i;
FpElement r = x0.subtract(y.getX0());
FpElement i = x1.subtract(y.getX1());

r = x0.subtract(y.getX0());
i = x1.subtract(y.getX1());
return new Fp2ElementOpti(sikeParam, r, i);
}

Expand Down Expand Up @@ -168,15 +167,15 @@ public Fp2ElementOpti square() {

@Override
public Fp2Element pow(BigInteger n) {
throw new IllegalStateException("Not implemented yet");
throw new IllegalStateException();
kasahiti marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Calculate the square root of the element.
* @return Calculation result.
*/
public Fp2ElementOpti sqrt() {
throw new IllegalStateException("Not implemented yet");
throw new IllegalStateException(Constants.Exceptions.NOT_IMPLEMENTED);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.math.optimized.fp;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.math.api.FpElement;
import com.wultra.security.pqc.sike.param.SikeParam;
import com.wultra.security.pqc.sike.util.ByteEncoding;
Expand All @@ -40,9 +41,9 @@ public class FpElementOpti implements FpElement {
* @param sikeParam SIKE parameters.
*/
public FpElementOpti(SikeParam sikeParam) {
long[] value = new long[sikeParam.getFpWords()];
long[] val = new long[sikeParam.getFpWords()];
this.sikeParam = sikeParam;
this.value = value;
this.value = val;
}

/**
Expand All @@ -63,15 +64,15 @@ public FpElementOpti(SikeParam sikeParam, long[] value) {
public FpElementOpti(SikeParam sikeParam, BigInteger x) {
this.sikeParam = sikeParam;
// Convert element to Montgomery domain
long[] value = new long[sikeParam.getFpWords()];
long[] val = new long[sikeParam.getFpWords()];
int primeSize = (sikeParam.getPrime().bitLength() + 7) / 8;
byte[] encoded = ByteEncoding.toByteArray(x, primeSize);
for (int i = 0; i < primeSize; i++) {
int j = i / 8;
int k = i % 8;
value[j] |= (Byte.toUnsignedLong(encoded[i]) << (8 * k));
val[j] |= (Byte.toUnsignedLong(encoded[i]) << (8 * k));
}
FpElementOpti a = new FpElementOpti(sikeParam, value);
FpElementOpti a = new FpElementOpti(sikeParam, val);
FpElementOpti b = (FpElementOpti) a.multiply(sikeParam.getPR2());
FpElementOpti reduced = b.reduceMontgomery();
this.value = new long[sikeParam.getFpWords()];
Expand Down Expand Up @@ -261,7 +262,7 @@ public FpElement square() {

@Override
public FpElement inverse() {
throw new IllegalStateException("Not implemented yet");
throw new IllegalStateException(Constants.Exceptions.NOT_IMPLEMENTED);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
*/
public class UnsignedLong {

/**
* Private constructor
*/
private UnsignedLong() {

}

/**
* Add two unsigned long values with carry.
* @param x First unsigned long value.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.wultra.security.pqc.sike.math.reference;

import com.wultra.security.pqc.sike.Constants;
import com.wultra.security.pqc.sike.math.api.Fp2Element;
import com.wultra.security.pqc.sike.math.api.Fp2Point;
import com.wultra.security.pqc.sike.param.SikeParam;
Expand Down Expand Up @@ -68,7 +69,7 @@ public Fp2Element getY() {
*/
@Override
public Fp2Element getZ() {
throw new InvalidParameterException("Invalid point coordinate");
throw new InvalidParameterException(Constants.Exceptions.INVALID_POINT_COORDINATE);
}

@Override
Expand Down
Loading