Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace libsodium with cryptology #558

Merged
merged 22 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d6aec07
use bouncycastle in cryptosign auth
muzzammilshahid Feb 14, 2024
9262042
add missing space
muzzammilshahid Feb 14, 2024
5b1b713
add unit tests for CryptosignAuth
muzzammilshahid Feb 19, 2024
0f1c292
replace libsodium with bouncy castle in SecretBox
muzzammilshahid Feb 24, 2024
967e127
add missing EOL
muzzammilshahid Feb 24, 2024
838b6b8
add function to create sealedbox nonce
om26er Feb 26, 2024
b1e88c6
add function to compute shared secret for sealedbox
om26er Feb 26, 2024
cdcc45e
implement the libsodium compatible seal function
om26er Feb 26, 2024
8ce13a5
implement the libsodium compatible unseal function
om26er Feb 26, 2024
af76c2c
make encrypt to only use the new code
om26er Feb 26, 2024
2ce33d2
Merge pull request #2 from om26er/sealedbox-bouncy
muzzammilshahid Feb 26, 2024
c6f45a7
remove dependency of libsodium
muzzammilshahid Feb 26, 2024
41b71b9
use correct version of web3j
muzzammilshahid Feb 26, 2024
fbdd505
use correct dependencies
muzzammilshahid Feb 26, 2024
492a7f1
add HSalsa20 implementation based on bouncy castle
muzzammilshahid Feb 26, 2024
5ec6bda
make HSALSA20_SEED global,static variable
muzzammilshahid Feb 26, 2024
b0300d7
add lisence for HSalsa20
muzzammilshahid Feb 26, 2024
cffc968
update web3j and java
muzzammilshahid Feb 27, 2024
0910973
use cryptology
muzzammilshahid Mar 6, 2024
e0a1b0d
exclude bouncy-castle from cryptology
muzzammilshahid Mar 6, 2024
9bf9cf5
remove unnecessary checkLength() function
muzzammilshahid Mar 6, 2024
3ebb097
update cryptology
muzzammilshahid Mar 20, 2024
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
23 changes: 14 additions & 9 deletions autobahn/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,25 @@ dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.16.1'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.16.1'
implementation 'org.msgpack:jackson-dataformat-msgpack:0.9.8'
implementation 'org.web3j:core:5.0.0'
implementation 'org.web3j:abi:5.0.0'
implementation 'org.web3j:utils:5.0.0'
implementation('io.xconn:cryptology:1.0.1') {
exclude group: "org.bouncycastle", module: "bcprov-jdk18on"
}
if (IS_ANDROID) {
implementation 'com.github.joshjdevl.libsodiumjni:libsodium-jni-aar:2.0.2'
} else {
implementation 'com.github.joshjdevl.libsodiumjni:libsodium-jni:2.0.2'
implementation 'org.web3j:core:4.8.8-android'
implementation 'org.web3j:abi:4.8.8-android'
implementation 'org.web3j:utils:4.8.8-android'
} else{
implementation 'org.web3j:core:4.11.0'
implementation 'org.web3j:abi:4.11.0'
implementation 'org.web3j:utils:4.11.0'
implementation 'org.json:json:20240205'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.5'
}
if (IS_NETTY) {
implementation 'io.netty:netty-codec-http:4.1.106.Final'
implementation 'io.netty:netty-handler:4.1.106.Final'
}
testImplementation 'junit:junit:4.13.2'
}

// Create the pom configuration:
Expand Down Expand Up @@ -174,8 +179,8 @@ if (IS_ANDROID) {
jar {
version = relVersion
}
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

afterEvaluate {
Expand All @@ -187,7 +192,7 @@ afterEvaluate {
artifactId ARTIFACT_ANDROID
} else {
from components.java
artifactId IS_NEXT ? ARTIFACT_NEXT: ARTIFACT_JAVA
artifactId IS_NEXT ? ARTIFACT_NEXT : ARTIFACT_JAVA
}

artifact sourcesJar
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
package io.crossbar.autobahn.wamp.auth;

import org.libsodium.jni.crypto.Random;
import org.libsodium.jni.keys.SigningKey;
import org.libsodium.jni.keys.VerifyKey;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import org.bouncycastle.util.encoders.Hex;

import io.xconn.cryptology.CryptoSign;
import io.xconn.cryptology.KeyPair;

import io.crossbar.autobahn.utils.AuthUtil;
import io.crossbar.autobahn.utils.Pair;
import io.crossbar.autobahn.wamp.Session;
import io.crossbar.autobahn.wamp.interfaces.IAuthenticator;
import io.crossbar.autobahn.wamp.types.Challenge;
import io.crossbar.autobahn.wamp.types.ChallengeResponse;

import static org.libsodium.jni.SodiumConstants.SECRETKEY_BYTES;

public class CryptosignAuth implements IAuthenticator {
public static final String authmethod = "cryptosign";
Expand All @@ -28,22 +28,21 @@ public class CryptosignAuth implements IAuthenticator {
private final byte[] privateKeyRaw;

public static Pair<String, String> generateSigningKeyPair() {
VerifyKey key = new VerifyKey(new Random().randomBytes(SECRETKEY_BYTES));
SigningKey signingKey = new SigningKey(key.toBytes());
KeyPair keyPair = CryptoSign.generateKeyPair();

String privateKey = AuthUtil.toHexString(key.toBytes());
String publicKey = AuthUtil.toHexString(signingKey.getVerifyKey().toBytes());
String publicKeyHex = Hex.toHexString(keyPair.getPublicKey());
String privateKeyHex = Hex.toHexString(keyPair.getPrivateKey());

return new Pair<>(publicKey, privateKey);
return new Pair<>(publicKeyHex, privateKeyHex);
}

public CryptosignAuth(String authid, String privateKey) {
this(authid, privateKey, getPublicKey(AuthUtil.toBinary(privateKey)));
}

public static String getPublicKey(byte[] privateKeyRaw) {
SigningKey signingKey = new SigningKey(privateKeyRaw);
return AuthUtil.toHexString(signingKey.getVerifyKey().toBytes());
byte[] publicKeyBytes = CryptoSign.getPublicKey(privateKeyRaw);
return AuthUtil.toHexString(publicKeyBytes);
}

public CryptosignAuth(String authid, String privkey, Map<String, Object> authextra) {
Expand All @@ -68,8 +67,7 @@ public CryptosignAuth(String authid, File privateKeyFile) {
}
}

public CryptosignAuth(String authid, String authrole, String privkey,
Map<String, Object> authextra) {
public CryptosignAuth(String authid, String authrole, String privkey, Map<String, Object> authextra) {
this.authid = authid;
this.authrole = authrole;
this.authextra = authextra;
Expand All @@ -85,8 +83,7 @@ public CompletableFuture<ChallengeResponse> onChallenge(Session session, Challen
String hexChallenge = (String) challenge.extra.get("challenge");
byte[] rawChallenge = AuthUtil.toBinary(hexChallenge);

SigningKey key = new SigningKey(privateKeyRaw);
byte[] signed = key.sign(rawChallenge);
byte[] signed = CryptoSign.sign(privateKeyRaw, rawChallenge);

String signatureHex = AuthUtil.toHexString(signed);
String res = signatureHex + hexChallenge;
Expand Down
23 changes: 11 additions & 12 deletions autobahn/src/main/java/xbr/network/KeySeries.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@

package xbr.network;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;

import org.libsodium.jni.SodiumConstants;
import org.libsodium.jni.crypto.Random;
import org.web3j.utils.Numeric;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Consumer;

import static io.xconn.cryptology.Util.generateRandomBytesArray;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;

import org.web3j.utils.Numeric;

import xbr.network.crypto.SealedBox;
import xbr.network.crypto.SecretBox;

Expand Down Expand Up @@ -94,8 +94,7 @@ byte[] getPrice() {
}

Map<String, Object> encrypt(Object payload) throws JsonProcessingException {
byte[] nonce = new Random().randomBytes(
SodiumConstants.XSALSA20_POLY1305_SECRETBOX_NONCEBYTES);
byte[] nonce = generateRandomBytesArray(Util.NONCE_SIZE);

Map<String, Object> data = new HashMap<>();
data.put("id", mID);
Expand All @@ -112,8 +111,8 @@ byte[] encryptKey(byte[] keyID, byte[] buyerPubKey) {
}

private void onRotate() {
mID = new Random().randomBytes(16);
mKey = new Random().randomBytes(SodiumConstants.XSALSA20_POLY1305_SECRETBOX_KEYBYTES);
mID = generateRandomBytesArray(16);
mKey = generateRandomBytesArray(Util.SECRET_KEY_LEN);
mBox = new SecretBox(mKey);

Map<String, Object> data = new HashMap<>();
Expand Down
11 changes: 5 additions & 6 deletions autobahn/src/main/java/xbr/network/SimpleBuyer.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;

import org.libsodium.jni.SodiumConstants;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.ECKeyPair;
import org.web3j.utils.Numeric;
Expand All @@ -27,6 +26,8 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;

import io.xconn.cryptology.KeyPair;

import io.crossbar.autobahn.utils.ABLogger;
import io.crossbar.autobahn.utils.IABLogger;
import io.crossbar.autobahn.wamp.Session;
Expand All @@ -36,8 +37,6 @@
import xbr.network.pojo.Quote;
import xbr.network.pojo.Receipt;

import static org.libsodium.jni.NaCl.sodium;

public class SimpleBuyer {

private static final IABLogger LOGGER = ABLogger.getLogger(SimpleBuyer.class.getName());
Expand Down Expand Up @@ -69,9 +68,9 @@ public SimpleBuyer(String marketMakerAddr, String buyerKey, BigInteger maxPrice)
mEthPublicKey = mECKey.getPublicKey().toByteArray();
mEthAddr = Numeric.hexStringToByteArray(Credentials.create(mECKey).getAddress());

mPrivateKey = new byte[SodiumConstants.SECRETKEY_BYTES];
mPublicKey = new byte[SodiumConstants.PUBLICKEY_BYTES];
sodium().crypto_box_keypair(mPublicKey, mPrivateKey);
KeyPair pubPriKeyPair = io.xconn.cryptology.SealedBox.generateKeyPair();
mPublicKey = pubPriKeyPair.getPublicKey();
mPrivateKey = pubPriKeyPair.getPrivateKey();

mMaxPrice = maxPrice;
mKeys = new HashMap<>();
Expand Down
5 changes: 3 additions & 2 deletions autobahn/src/main/java/xbr/network/SimpleSeller.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

package xbr.network;

import static io.xconn.cryptology.Util.generateRandomBytesArray;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;

import org.libsodium.jni.crypto.Random;
import org.web3j.crypto.ECKeyPair;
import org.web3j.crypto.Keys;
import org.web3j.utils.Numeric;
Expand Down Expand Up @@ -93,7 +94,7 @@ public byte[] getPublicKey() {
private void onRotate(KeySeries series) {
mKeysMap.put(Numeric.toHexString(series.getID()), series);
long validFrom = Math.round(System.nanoTime() - 10 * Math.pow(10, 9));
byte[] signature = new Random().randomBytes(65);
byte[] signature = generateRandomBytesArray(65);

List<Object> args = new ArrayList<>();
args.add(series.getID());
Expand Down
3 changes: 3 additions & 0 deletions autobahn/src/main/java/xbr/network/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@

public class Util {

public static final int NONCE_SIZE = 24;
public static final int SECRET_KEY_LEN = 32;

public static BigInteger toXBR(int xbr) {
return BigInteger.valueOf(xbr).multiply(BigInteger.valueOf(10).pow(18));
}
Expand Down
30 changes: 7 additions & 23 deletions autobahn/src/main/java/xbr/network/crypto/SealedBox.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package xbr.network.crypto;

import org.libsodium.jni.encoders.Encoder;

import static org.libsodium.jni.NaCl.sodium;
import static org.libsodium.jni.SodiumConstants.PUBLICKEY_BYTES;
import static org.libsodium.jni.crypto.Util.isValid;
import static io.xconn.cryptology.SealedBox.seal;
import static io.xconn.cryptology.SealedBox.sealOpen;

public class SealedBox {

private static final int MAC_BYTES = 16;
private static int PUBLICKEY_BYTES = 32;
private static final int SEAL_BYTES = PUBLICKEY_BYTES + MAC_BYTES;

private static final byte[] HSALSA20_SEED = new byte[16];
private byte[] publicKey;
private byte[] privateKey;

Expand All @@ -22,9 +21,6 @@ public SealedBox(byte[] publicKey) {
this.privateKey = null;
}

public SealedBox(String publicKey, Encoder encoder) {
this(encoder.decode(publicKey));
}

public SealedBox(byte[] publicKey, byte[] privateKey) {
if (publicKey == null) {
Expand All @@ -37,23 +33,11 @@ public SealedBox(byte[] publicKey, byte[] privateKey) {
this.privateKey = privateKey;
}

public SealedBox(String publicKey, String privateKey, Encoder encoder) {
this(encoder.decode(publicKey), encoder.decode(privateKey));
}

public byte[] encrypt(byte[] message) {
byte[] ct = new byte[message.length + SEAL_BYTES];
isValid(sodium().crypto_box_seal(
ct, message, message.length, publicKey),
"Encryption failed");
return ct;
return seal(message, publicKey);
}

public byte[] decrypt(byte[] ciphertext) {
byte[] message = new byte[ciphertext.length - SEAL_BYTES];
isValid(sodium().crypto_box_seal_open(
message, ciphertext, ciphertext.length, publicKey, privateKey),
"Decryption failed. Ciphertext failed verification");
return message;
public byte[] decrypt(byte[] message) {
return sealOpen(message, privateKey);
}
}
60 changes: 17 additions & 43 deletions autobahn/src/main/java/xbr/network/crypto/SecretBox.java
Original file line number Diff line number Diff line change
@@ -1,65 +1,39 @@
package xbr.network.crypto;

import org.libsodium.jni.crypto.Random;
import org.libsodium.jni.crypto.Util;
import org.libsodium.jni.encoders.Encoder;

import java.util.Arrays;

import static org.libsodium.jni.NaCl.sodium;
import static org.libsodium.jni.SodiumConstants.BOXZERO_BYTES;
import static org.libsodium.jni.SodiumConstants.XSALSA20_POLY1305_SECRETBOX_KEYBYTES;
import static org.libsodium.jni.SodiumConstants.XSALSA20_POLY1305_SECRETBOX_NONCEBYTES;
import static org.libsodium.jni.SodiumConstants.ZERO_BYTES;
import static org.libsodium.jni.crypto.Util.checkLength;
import static org.libsodium.jni.crypto.Util.isValid;
import static org.libsodium.jni.crypto.Util.removeZeros;
import static io.xconn.cryptology.SecretBox.box;
import static io.xconn.cryptology.SecretBox.boxOpen;
import static io.xconn.cryptology.Util.checkLength;
import static io.xconn.cryptology.Util.generateRandomBytesArray;

import static xbr.network.Util.NONCE_SIZE;
import static xbr.network.Util.SECRET_KEY_LEN;

public class SecretBox {

private byte[] mKey;
private Encoder mEncoder;
private final byte[] mKey;

public SecretBox(byte[] key) {
checkLength(key, XSALSA20_POLY1305_SECRETBOX_KEYBYTES);
mEncoder = Encoder.RAW;
mKey = key;
checkLength(key, SECRET_KEY_LEN);
mKey = Arrays.copyOf(key, key.length);
}

public byte[] encrypt(byte[] message) {
byte[] nonce = new Random().randomBytes(XSALSA20_POLY1305_SECRETBOX_NONCEBYTES);
byte[] nonce = generateRandomBytesArray(NONCE_SIZE);
return encrypt(nonce, message);
}

public byte[] encrypt(byte[] nonce, byte[] message) {
checkLength(nonce, XSALSA20_POLY1305_SECRETBOX_NONCEBYTES);
byte[] msg = org.libsodium.jni.crypto.Util.prependZeros(ZERO_BYTES, message);
byte[] ct = org.libsodium.jni.crypto.Util.zeros(msg.length);
isValid(sodium().crypto_secretbox_xsalsa20poly1305(ct, msg, msg.length,
nonce, mKey), "Encryption failed");
byte[] cipherWithoutNonce = removeZeros(BOXZERO_BYTES, ct);
byte[] ciphertext = new byte[cipherWithoutNonce.length +
XSALSA20_POLY1305_SECRETBOX_NONCEBYTES];
public byte[] encrypt(byte[] nonce, byte[] plaintext) {
byte[] cipherWithoutNonce = box(nonce, plaintext, mKey);
byte[] ciphertext = new byte[cipherWithoutNonce.length + NONCE_SIZE];
System.arraycopy(nonce, 0, ciphertext, 0, nonce.length);
System.arraycopy(cipherWithoutNonce, 0, ciphertext, nonce.length,
cipherWithoutNonce.length);
System.arraycopy(cipherWithoutNonce, 0, ciphertext, nonce.length, cipherWithoutNonce.length);
return ciphertext;
}

public byte[] decrypt(byte[] ciphertext) {
byte[] nonce = Arrays.copyOfRange(ciphertext, 0, XSALSA20_POLY1305_SECRETBOX_NONCEBYTES);
byte[] message = Arrays.copyOfRange(ciphertext, XSALSA20_POLY1305_SECRETBOX_NONCEBYTES,
ciphertext.length);
return decrypt(nonce, message);
}

public byte[] decrypt(byte[] nonce, byte[] ciphertext) {
checkLength(nonce, XSALSA20_POLY1305_SECRETBOX_NONCEBYTES);
byte[] ct = org.libsodium.jni.crypto.Util.prependZeros(BOXZERO_BYTES, ciphertext);
byte[] message = Util.zeros(ct.length);
isValid(sodium().crypto_secretbox_xsalsa20poly1305_open(message, ct,
ct.length, nonce, mKey), "Decryption failed. Ciphertext failed verification");
return removeZeros(ZERO_BYTES, message);
byte[] nonce = Arrays.copyOfRange(ciphertext, 0, NONCE_SIZE);
byte[] message = Arrays.copyOfRange(ciphertext, NONCE_SIZE, ciphertext.length);
return boxOpen(nonce, message, mKey);
}
}
Loading
Loading