Browse Source

replace paillier encryption implementations in the MIT license with ones in the Apache 2.0

tags/1.0.0
zhanglin33 5 years ago
parent
commit
73b53a7aa3
15 changed files with 38 additions and 1097 deletions
  1. +6
    -19
      source/crypto/crypto-adv/pom.xml
  2. +25
    -12
      source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/mpc/MultiSum.java
  3. +0
    -98
      source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/KeyPair.java
  4. +0
    -165
      source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/KeyPairBuilder.java
  5. +0
    -61
      source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/PaillierUtils.java
  6. +0
    -75
      source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/PrivateKey.java
  7. +0
    -129
      source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/PublicKey.java
  8. +7
    -9
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/mpc/MultiSumTest.java
  9. +0
    -58
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/DecryptionTest.java
  10. +0
    -90
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/HomomorphicPropertiesTest.java
  11. +0
    -43
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/JPaillierTest.java
  12. +0
    -44
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/KeyPairBuilderPrivateKeyTest.java
  13. +0
    -57
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/KeyPairBuilderPublicKeyTest.java
  14. +0
    -113
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/KeyPairBuilderTest.java
  15. +0
    -124
      source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/ResolveTest.java

+ 6
- 19
source/crypto/crypto-adv/pom.xml View File

@@ -27,20 +27,6 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>net.i2p.crypto</groupId>
<artifactId>eddsa</artifactId>
@@ -52,11 +38,6 @@
<version>5.1.0</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jd.blockchain</groupId>
<artifactId>crypto-framework</artifactId>
@@ -64,5 +45,11 @@
<scope>compile</scope>
</dependency>

<dependency>
<groupId>com.n1analytics</groupId>
<artifactId>javallier_2.10</artifactId>
<version>0.6.0</version>
</dependency>

</dependencies>
</project>

+ 25
- 12
source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/mpc/MultiSum.java View File

@@ -2,6 +2,8 @@ package com.jd.blockchain.crypto.mpc;

import java.math.BigInteger;

import com.n1analytics.paillier.PaillierPrivateKey;
import com.n1analytics.paillier.PaillierPublicKey;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.agreement.ECDHBasicAgreement;
@@ -12,9 +14,6 @@ import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.PaillierUtils;
import com.jd.blockchain.crypto.paillier.PublicKey;
import com.jd.blockchain.crypto.utils.sm.SM2Utils;
import com.jd.blockchain.crypto.utils.sm.SM3Utils;
import com.jd.blockchain.utils.io.BytesUtils;
@@ -32,7 +31,6 @@ public class MultiSum {
this.ePubKey = (ECPublicKeyParameters) eKeyPair.getPublic();
this.curve = SM2Utils.getCurve();
this.domainParams = SM2Utils.getDomainParams();

}

public BigInteger calculateAgreement(CipherParameters otherEPubKey){
@@ -47,20 +45,23 @@ public class MultiSum {
return new BigInteger(1,SM3Utils.hash(inputBytes));
}

public static BigInteger encryptBlindedMsg(PublicKey encKey, BigInteger msg, BigInteger frontShare, BigInteger rearShare){
return encKey.encrypt(msg.add(frontShare).subtract(rearShare).mod(encKey.getN()));
public static BigInteger encryptBlindedMsg(PaillierPublicKey encKey, BigInteger msg, BigInteger frontShare, BigInteger rearShare){
BigInteger modulus = encKey.getModulus();
BigInteger plaintext = msg.add(frontShare).subtract(rearShare).mod(modulus);
return encKey.raw_encrypt(plaintext);
}

public static BigInteger aggregateCiphertexts(PublicKey encKey, BigInteger... bigIntegersList){
public static BigInteger aggregateCiphertexts(PaillierPublicKey encKey, BigInteger... bigIntegers){
BigInteger aggregatedCiphertext = BigInteger.ONE;
for (BigInteger entry : bigIntegersList) {
aggregatedCiphertext = aggregatedCiphertext.multiply(entry).mod(encKey.getnSquared());
BigInteger modulusSquared = encKey.getModulusSquared();
for (BigInteger entry : bigIntegers) {
aggregatedCiphertext = aggregatedCiphertext.multiply(entry).mod(modulusSquared);
}
return aggregatedCiphertext;
}

public static BigInteger decrypt(KeyPair keyPair, BigInteger ciphertext){
return keyPair.decrypt(ciphertext);
public static BigInteger decrypt(PaillierPrivateKey decKey, BigInteger ciphertext){
return decKey.raw_decrypt(ciphertext);
}

public ECPublicKeyParameters getEPubKey(){return ePubKey;}
@@ -79,7 +80,7 @@ public class MultiSum {
}

public byte[] getEPrivKeyBytes(){
return PaillierUtils.BigIntegerToLBytes(ePrivKey.getD(),32);
return BigIntegerToLBytes(ePrivKey.getD(),32);
}

public ECPublicKeyParameters resolveEPubKey(byte[] ePubKeyBytes){
@@ -95,4 +96,16 @@ public class MultiSum {
return new ECPrivateKeyParameters(new BigInteger(1,ePrivKeyBytes),domainParams);
}

// To convert BigInteger to byte[] whose length is l
private static byte[] BigIntegerToLBytes(BigInteger b, int l){
byte[] tmp = b.toByteArray();
byte[] result = new byte[l];
if (tmp.length > result.length) {
System.arraycopy(tmp, tmp.length - result.length, result, 0, result.length);
}
else {
System.arraycopy(tmp,0,result,result.length-tmp.length,tmp.length);
}
return result;
}
}

+ 0
- 98
source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/KeyPair.java View File

@@ -1,98 +0,0 @@
package com.jd.blockchain.crypto.paillier;

import java.math.BigInteger;
import java.util.List;

import com.jd.blockchain.utils.io.BytesUtils;

/**
* The MIT License (MIT)
*
* Copyright (c) 2014 Hendrik Kunert
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/**
* A class that holds a pair of associated public and private keys.
*/
public class KeyPair {
private final PrivateKey privateKey;
private final PublicKey publicKey;
private final BigInteger upperBound;

public KeyPair(PrivateKey privateKey, PublicKey publicKey, BigInteger upperBound) {
this.privateKey = privateKey;
this.publicKey = publicKey;
this.upperBound = upperBound;
}

public KeyPair(byte[] privKeyBytes,byte[] pubKeyBytes,byte[] upperBoundBytes){
this.privateKey = new PrivateKey(privKeyBytes);
this.publicKey = new PublicKey(pubKeyBytes);
this.upperBound = new BigInteger(upperBoundBytes);
}

public KeyPair(byte[] keyPairBytes){
List<byte[]> list = PaillierUtils.split(keyPairBytes, "##KeyPair##".getBytes());
this.privateKey = new PrivateKey(list.get(0));
this.publicKey = new PublicKey(list.get(1));
this.upperBound = new BigInteger(list.get(2));
}

public PrivateKey getPrivateKey() {
return privateKey;
}

public PublicKey getPublicKey() {
return publicKey;
}

public BigInteger getUpperBound() { return upperBound; }

/**
* Decrypts the given ciphertext.
*
* @param c The ciphertext that should be decrypted.
* @return The corresponding plaintext. If an upper bound was given to {@link KeyPairBuilder},
* the result can also be negative. See {@link KeyPairBuilder#upperBound(BigInteger)} for details.
*/
public final BigInteger decrypt(BigInteger c) {

BigInteger n = publicKey.getN();
BigInteger nSquare = publicKey.getnSquared();
BigInteger lambda = privateKey.getLambda();

BigInteger u = privateKey.getPreCalculatedDenominator();

BigInteger p = c.modPow(lambda, nSquare).subtract(BigInteger.ONE).divide(n).multiply(u).mod(n);

if (upperBound != null && p.compareTo(upperBound) > 0) {
p = p.subtract(n);
}

return p;
}

public byte[] getUpperBoundBytes(){ return upperBound.toByteArray(); }

public byte[] getKeyPairBytes(){
return BytesUtils.concat(privateKey.getPrivKeyBytes(),"##KeyPair##".getBytes(),publicKey.getPubKeyBytes(),"##KeyPair##".getBytes(),upperBound.toByteArray());
}
}

+ 0
- 165
source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/KeyPairBuilder.java View File

@@ -1,165 +0,0 @@
package com.jd.blockchain.crypto.paillier;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
/**
* The MIT License (MIT)
*
* Copyright (c) 2014 Hendrik Kunert
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

/**
* A class that is used for generating a pair of associated public and private
* keys.
*
* @see KeyPair
*/
public class KeyPairBuilder {

private int bits = 1024;

private int certainty = 0;

private Random rng;

private BigInteger upperBound;

/**
* Sets the size of the key to be created.
* <p>
* The default size is 1024 bits.
*
* @param bits The size of the key in bits.
* @return This instance of KeyPairBuilder for method chaining.
*/
public KeyPairBuilder bits(int bits) {
this.bits = bits;
return this;
}

/**
* See {@link BigInteger#BigInteger(int, int, Random)} for more details.
* <p>
* The default value is 0.
*
* @return This instance of KeyPairBuilder for method chaining.
*/
public KeyPairBuilder certainty(int certainty) {
this.certainty = certainty;
return this;
}

/**
* Sets the random number generator that is used for the generation of
* internally needed prime numbers.
* <p>
* The default is {@link SecureRandom}.
* <p>
* <b>Warning:</b>
* The change of this value affects the security of the whole cryptographic
* system.
*
* @param rng The random number generator that should be used instead of
* {@link SecureRandom}.
* @return This instance of KeyPairBuilder for method chaining.
*/
public KeyPairBuilder randomNumberGenerator(Random rng) {
this.rng = rng;
return this;
}

/**
* Sets an upper bound that is used for decrypting ciphertexts representing a negative value.
* <p>
* In most cases the upper bound should be the same as of the underlying number system -
* for example {@link Integer#MAX_VALUE}.
*
* @param b The upper bound.
* @return This instance of KeyPairBuilder for method chaining.
*/
public KeyPairBuilder upperBound(BigInteger b) {
this.upperBound = b;
return this;
}

/**
* Creates a pair of associated public and private keys.
*
* @return The pair of associated public and private keys.
*/
public KeyPair generateKeyPair() {
if (rng == null) {
rng = new SecureRandom();
}

BigInteger p, q;
int length = bits / 2;
if (certainty > 0) {
p = new BigInteger(length, certainty, rng);
q = new BigInteger(length, certainty, rng);
} else {
p = BigInteger.probablePrime(length, rng);
q = BigInteger.probablePrime(length, rng);
}

BigInteger n = p.multiply(q);
BigInteger nSquared = n.multiply(n);

BigInteger pMinusOne = p.subtract(BigInteger.ONE);
BigInteger qMinusOne = q.subtract(BigInteger.ONE);

BigInteger lambda = this.lcm(pMinusOne, qMinusOne);

BigInteger g;
BigInteger helper;

do {
g = new BigInteger(bits, rng);
helper = calculateL(g.modPow(lambda, nSquared), n);

} while (!helper.gcd(n).equals(BigInteger.ONE));

PublicKey publicKey = new PublicKey(n, nSquared, g, bits);
PrivateKey privateKey = new PrivateKey(lambda, helper.modInverse(n));

return new KeyPair(privateKey, publicKey, upperBound);

}

// TODO separate this somewhere
private BigInteger calculateL(BigInteger u, BigInteger n) {
BigInteger result = u.subtract(BigInteger.ONE);
result = result.divide(n);
return result;
}

// TODO add to own BigInteger extended class
private BigInteger lcm(BigInteger a, BigInteger b) {
BigInteger result;
BigInteger gcd = a.gcd(b);

result = a.abs().divide(gcd);
result = result.multiply(b.abs());

return result;
}
}

+ 0
- 61
source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/PaillierUtils.java View File

@@ -1,61 +0,0 @@
package com.jd.blockchain.crypto.paillier;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class PaillierUtils {

// To convert BigInteger to byte[] whose length is l
public static byte[] BigIntegerToLBytes(BigInteger b, int l){
byte[] tmp = b.toByteArray();
byte[] result = new byte[l];
if (tmp.length > result.length) {
System.arraycopy(tmp, tmp.length - result.length, result, 0, result.length);
}
else {
System.arraycopy(tmp,0,result,result.length-tmp.length,tmp.length);
}
return result;
}

public static byte[] intToBytes(int i){
byte[] result = new byte[4];
result[0] = (byte) (i >> 24);
result[1] = (byte) (i >> 16);
result[2] = (byte) (i >> 8);
result[3] = (byte) (i);
return result;
}

public static int bytesToInt(byte[] array){
int result = 0;
result |= ((array[0] & 0xFF) << 24);
result |= ((array[1] & 0xFF) << 16);
result |= ((array[2] & 0xFF) << 8);
result |= ((array[3] & 0xFF));
return result;
}

public static List<byte[]> split(byte[] array, byte[] delimiter) {
List<byte[]> byteArrays = new LinkedList<>();
if (delimiter.length == 0) {
return byteArrays;
}
int begin = 0;

outer:
for (int i = 0; i < array.length - delimiter.length + 1; i++) {
for (int j = 0; j < delimiter.length; j++) {
if (array[i + j] != delimiter[j]) {
continue outer;
}
}
byteArrays.add(Arrays.copyOfRange(array, begin, i));
begin = i + delimiter.length;
}
byteArrays.add(Arrays.copyOfRange(array, begin, array.length));
return byteArrays;
}
}

+ 0
- 75
source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/PrivateKey.java View File

@@ -1,75 +0,0 @@
package com.jd.blockchain.crypto.paillier;

import java.math.BigInteger;
import java.util.List;
/**
* The MIT License (MIT)
*
* Copyright (c) 2014 Hendrik Kunert
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

import com.jd.blockchain.utils.io.BytesUtils;

/**
* A class that represents the private part of the Paillier key pair.
*/
public class PrivateKey {

private final BigInteger lambda;
private final BigInteger preCalculatedDenominator;

public PrivateKey(BigInteger lambda, BigInteger preCalculatedDenominator) {
this.lambda = lambda;

this.preCalculatedDenominator = preCalculatedDenominator;
}

public PrivateKey(byte[] lambdaBytes, byte[] preCalculatedDenominatorBytes){
this.lambda = new BigInteger(lambdaBytes);
this.preCalculatedDenominator = new BigInteger(preCalculatedDenominatorBytes);
}

public PrivateKey(byte[] privKeyBytes){
List<byte[]> list = PaillierUtils.split(privKeyBytes, "##PrivateKey##".getBytes());
this.lambda = new BigInteger(list.get(0));
this.preCalculatedDenominator = new BigInteger(list.get(1));
}

public BigInteger getLambda() {
return lambda;
}

public BigInteger getPreCalculatedDenominator() {
return preCalculatedDenominator;
}

public byte[] getLambdaBytes(){
return lambda.toByteArray();
}

public byte[] getPreCalculatedDenominatorBytes(){
return preCalculatedDenominator.toByteArray();
}

public byte[] getPrivKeyBytes(){
return BytesUtils.concat(getLambdaBytes(),"##PrivateKey##".getBytes(),getPreCalculatedDenominatorBytes());
}
}

+ 0
- 129
source/crypto/crypto-adv/src/main/java/com/jd/blockchain/crypto/paillier/PublicKey.java View File

@@ -1,129 +0,0 @@
package com.jd.blockchain.crypto.paillier;

import java.math.BigInteger;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
/**
* The MIT License (MIT)
*
* Copyright (c) 2014 Hendrik Kunert
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

import com.jd.blockchain.utils.io.ByteArray;
import com.jd.blockchain.utils.io.BytesUtils;

/**
* A class that represents the public part of the Paillier key pair.
* <p>
* As in all asymmetric cryptographic systems it is responsible for the
* encryption.
* <p>
* Additional instructions for the decryption can be found on {@link KeyPair}.
*
* @see KeyPair
*/
public class PublicKey {
private final int bits;
private final BigInteger n;
private final BigInteger nSquared;
private final BigInteger g;

public PublicKey(BigInteger n, BigInteger nSquared, BigInteger g, int bits) {
this.n = n;
this.nSquared = nSquared;
this.bits = bits;
this.g = g;
}

public PublicKey(byte[] nBytes, byte[] nSquaredBytes, byte[] gBytes, byte[] bitsBytes) {
this.n = new BigInteger(nBytes);
this.nSquared = new BigInteger(nSquaredBytes);
this.g = new BigInteger(gBytes);
this.bits = PaillierUtils.bytesToInt(bitsBytes);
}

public PublicKey(byte[] pubKeyBytes){
List<byte[]> list = PaillierUtils.split(pubKeyBytes, "##PublicKey##".getBytes());
this.n = new BigInteger(list.get(0));
this.nSquared = new BigInteger(list.get(1));
this.g = new BigInteger(list.get(2));
this.bits = PaillierUtils.bytesToInt(list.get(3));
}


public int getBits() {
return bits;
}

public BigInteger getN() {
return n;
}

public BigInteger getnSquared() {
return nSquared;
}

public BigInteger getG() {
return g;
}

/**
* Encrypts the given plaintext.
*
* @param m The plaintext that should be encrypted.
* @return The corresponding ciphertext.
*/
public final BigInteger encrypt(BigInteger m) {

BigInteger r;
do {
r = new BigInteger(bits, new Random());
} while (r.compareTo(n) >= 0);

BigInteger result = g.modPow(m, nSquared);
BigInteger x = r.modPow(n, nSquared);

result = result.multiply(x);
result = result.mod(nSquared);

return result;
}

public byte[] getBitsBytes(){
return PaillierUtils.intToBytes(bits);
}

public byte[] getNBytes(){ return n.toByteArray(); }

public byte[] getNSquaredBytes(){
return nSquared.toByteArray();
}

public byte[] getGBytes(){
return g.toByteArray();
}

public byte[] getPubKeyBytes(){
return BytesUtils.concat(getNBytes(),"##PublicKey##".getBytes(),getNSquaredBytes(),"##PublicKey##".getBytes(),getGBytes(),"##PublicKey##".getBytes(),getBitsBytes());
}
}


+ 7
- 9
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/mpc/MultiSumTest.java View File

@@ -1,9 +1,8 @@
package test.com.jd.blockchain.crypto.mpc;

import com.jd.blockchain.crypto.mpc.MultiSum;
import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PublicKey;
import com.n1analytics.paillier.PaillierPrivateKey;
import com.n1analytics.paillier.PaillierPublicKey;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.util.encoders.Hex;
@@ -16,14 +15,13 @@ import static org.junit.Assert.*;

public class MultiSumTest {

private KeyPair keyPair;
private PublicKey encKey;
private PaillierPrivateKey decKey;
private PaillierPublicKey encKey;

@Before
public void init() {
KeyPairBuilder keygen = new KeyPairBuilder();
keyPair = keygen.generateKeyPair();
encKey = keyPair.getPublicKey();
decKey = PaillierPrivateKey.create(2048);
encKey = decKey.getPublicKey();
}
@Test
@@ -72,7 +70,7 @@ public class MultiSumTest {

BigInteger aggregatedCiphertext = MultiSum.aggregateCiphertexts(encKey,c1,c2,c3);

BigInteger decryptedValue = MultiSum.decrypt(keyPair,aggregatedCiphertext);
BigInteger decryptedValue = MultiSum.decrypt(decKey,aggregatedCiphertext);

assertEquals(expectedSum,decryptedValue);
}


+ 0
- 58
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/DecryptionTest.java View File

@@ -1,58 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PublicKey;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;

import static org.junit.Assert.assertEquals;

/**
* Created by kunerd on 22.09.15.
*/
@RunWith(value = Parameterized.class)
public class DecryptionTest {

@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(createTestParameter(Long.MIN_VALUE),
createTestParameter(Integer.MIN_VALUE),
createTestParameter(Short.MIN_VALUE),
createTestParameter(0),
createTestParameter(Short.MAX_VALUE),
createTestParameter(Integer.MAX_VALUE),
createTestParameter(Long.MAX_VALUE));
}

private BigInteger input;
private BigInteger expected;

public DecryptionTest(BigInteger input, BigInteger expected) {
this.input = input;
this.expected = expected;
}

@Test
public void test() {
KeyPair keyPair = new KeyPairBuilder().upperBound(BigInteger.valueOf(Long.MAX_VALUE))
.generateKeyPair();
PublicKey publicKey = keyPair.getPublicKey();

BigInteger encryptedData = publicKey.encrypt(input);

assertEquals(expected, keyPair.decrypt(encryptedData));
}

private static Object[] createTestParameter(long plaintext) {
BigInteger p = BigInteger.valueOf(plaintext);
return new Object[]{p, p};
}

}


+ 0
- 90
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/HomomorphicPropertiesTest.java View File

@@ -1,90 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PublicKey;
import org.junit.Before;
import org.junit.Test;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;

public class HomomorphicPropertiesTest {
private KeyPair keypair;
private PublicKey publicKey;

@Before
public void init() {
KeyPairBuilder keygen = new KeyPairBuilder();
this.keypair = keygen.generateKeyPair();
this.publicKey = keypair.getPublicKey();
}

@Test
public void testHomomorphicAddition() {
BigInteger plainA = BigInteger.valueOf(102);
BigInteger plainB = BigInteger.valueOf(203);

BigInteger encryptedA = publicKey.encrypt(plainA);
BigInteger encryptedB = publicKey.encrypt(plainB);

BigInteger decryptedProduct = keypair.decrypt(encryptedA.multiply(
encryptedB).mod(publicKey.getnSquared()));
BigInteger plainSum = plainA.add(plainB).mod(publicKey.getN());

assertEquals(decryptedProduct, plainSum);
}

@Test
public void testHomomorphicConstantMultiplication() {
BigInteger plainA = BigInteger.valueOf(14);
BigInteger plainB = BigInteger.valueOf(203);

BigInteger encryptedA = publicKey.encrypt(plainA);

BigInteger decryptedPow = keypair.decrypt(encryptedA.modPow(plainB,
publicKey.getnSquared()));
BigInteger plainSum = plainA.multiply(plainB).mod(publicKey.getN());

assertEquals(decryptedPow, plainSum);
}

@Test
public void testHomomorphicMultiplication() {
BigInteger plainA = BigInteger.valueOf(23);
BigInteger plainB = BigInteger.valueOf(234);

BigInteger encryptedA = publicKey.encrypt(plainA);
BigInteger decryptedPowA = keypair.decrypt(encryptedA.modPow(
plainB, publicKey.getnSquared()));
BigInteger plainSumA = plainA.multiply(plainB).mod(publicKey.getN());

assertEquals(decryptedPowA, plainSumA);

BigInteger encryptedB = publicKey.encrypt(plainB);
BigInteger decryptedPowB = keypair.decrypt(encryptedB.modPow(
plainA, publicKey.getnSquared()));
BigInteger plainSumB = plainA.multiply(plainB).mod(publicKey.getN());

assertEquals(decryptedPowB, plainSumB);

assertEquals(decryptedPowA, decryptedPowB);
}

@Test
public void testHomomorphicMultiplicationPowG() {
BigInteger plainA = BigInteger.valueOf(230);
BigInteger plainB = BigInteger.valueOf(100);

BigInteger g = publicKey.getG();

BigInteger encryptedA = publicKey.encrypt(plainA);
BigInteger decryptedPow = keypair.decrypt(encryptedA.multiply(g.modPow(
plainB, publicKey.getnSquared()).mod(publicKey.getnSquared())));

BigInteger plainSumA = plainA.add(plainB).mod(publicKey.getN());

assertEquals(decryptedPow, plainSumA);
}
}

+ 0
- 43
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/JPaillierTest.java View File

@@ -1,43 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PublicKey;
import org.junit.Before;
import org.junit.Test;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;

public class JPaillierTest {
private KeyPair keyPair;
private PublicKey publicKey;

@Before
public void init() {
KeyPairBuilder keygen = new KeyPairBuilder();
keyPair = keygen.generateKeyPair();
publicKey = keyPair.getPublicKey();
}

@Test
public void testEncryption() {
BigInteger plainData = BigInteger.valueOf(10);

BigInteger encryptedData = publicKey.encrypt(plainData);

assertNotEquals(plainData, encryptedData);
}

@Test
public void testDecyption() {
BigInteger plainData = BigInteger.valueOf(10);

BigInteger encryptedData = publicKey.encrypt(plainData);
BigInteger decryptedData = keyPair.decrypt(encryptedData);

assertEquals(plainData, decryptedData);
}
}

+ 0
- 44
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/KeyPairBuilderPrivateKeyTest.java View File

@@ -1,44 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PrivateKey;
import com.jd.blockchain.crypto.paillier.PublicKey;
import org.junit.Before;
import org.junit.Test;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;

public class KeyPairBuilderPrivateKeyTest {
private KeyPairBuilder keygen;
private KeyPair keypair;
private PrivateKey privateKey;

@Before
public void init() {
this.keygen = new KeyPairBuilder();
this.keypair = keygen.generateKeyPair();
this.privateKey = keypair.getPrivateKey();
}

@Test
public void testPreCalculatedDenominator() {
PublicKey publicKey = keypair.getPublicKey();

BigInteger preCalculatedDenominator = privateKey.getPreCalculatedDenominator();

BigInteger g = publicKey.getG();
BigInteger n = publicKey.getN();
BigInteger nSquared = publicKey.getnSquared();
BigInteger lambda = privateKey.getLambda();

BigInteger expected = g.modPow(lambda, nSquared);
expected = expected.subtract(BigInteger.ONE);
expected = expected.divide(n);
expected = expected.modInverse(n);

assertEquals(expected, preCalculatedDenominator);
}
}

+ 0
- 57
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/KeyPairBuilderPublicKeyTest.java View File

@@ -1,57 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PrivateKey;
import com.jd.blockchain.crypto.paillier.PublicKey;
import org.junit.Before;
import org.junit.Test;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;

public class KeyPairBuilderPublicKeyTest {

private KeyPair keypair;
private PublicKey publicKey;

@Before
public void init() {
KeyPairBuilder keygen = new KeyPairBuilder();
this.keypair = keygen.generateKeyPair();
this.publicKey = keypair.getPublicKey();
}

@Test
public void testBitsSetup() {
int BITS = 1024;
assertEquals(BITS, publicKey.getBits());
}

@Test
public void testCalculationOfNSquared() {

BigInteger n = publicKey.getN();
BigInteger nSquared = n.multiply(n);

assertEquals(nSquared, publicKey.getnSquared());
}

@Test
public void testCalculationOfGOfG() {
PrivateKey privateKey = keypair.getPrivateKey();

BigInteger n = publicKey.getN();
BigInteger nSquared = publicKey.getnSquared();
BigInteger g = publicKey.getG();
BigInteger lambda = privateKey.getLambda();

BigInteger l = g.modPow(lambda, nSquared);
l = l.subtract(BigInteger.ONE);
l = l.divide(n);

assertEquals(BigInteger.ONE, l.gcd(n));
}

}

+ 0
- 113
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/KeyPairBuilderTest.java View File

@@ -1,113 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import static org.junit.Assert.assertEquals;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import com.jd.blockchain.crypto.paillier.KeyPair;
import com.jd.blockchain.crypto.paillier.KeyPairBuilder;
import com.jd.blockchain.crypto.paillier.PrivateKey;
import com.jd.blockchain.crypto.paillier.PublicKey;

@RunWith(PowerMockRunner.class)
@PrepareForTest(KeyPairBuilder.class)
public class KeyPairBuilderTest {

private static final int BITS = 128;

private KeyPairBuilder keygen;
private PublicKey publicKey;
private PrivateKey privateKey;

private BigInteger p = BigInteger.valueOf(5);
private BigInteger q = BigInteger.valueOf(7);
private BigInteger g1 = BigInteger.valueOf(35);
private BigInteger g2 = BigInteger.valueOf(36);

private Random rng;

@Before
public void beforeEach() {
rng = PowerMockito.mock(SecureRandom.class);

keygen = new KeyPairBuilder()
.bits(BITS)
.randomNumberGenerator(rng);

PowerMockito.mockStatic(BigInteger.class);
}

private void prepareTest() throws Exception {

PowerMockito.when(BigInteger.probablePrime(BITS / 2, rng)).thenReturn(p, q);

PowerMockito.whenNew(BigInteger.class).withArguments(BITS, rng).thenReturn(g1, g2);

KeyPair keypair = keygen.generateKeyPair();

publicKey = keypair.getPublicKey();
privateKey = keypair.getPrivateKey();
}

@Test
public void computationOfN() throws Exception {
prepareTest();

BigInteger e = p.multiply(q);
BigInteger a = publicKey.getN();

assertEquals(e, a);
}


@Test
public void computationOfLambda() throws Exception {
BigInteger e = new BigInteger("12");

prepareTest();

BigInteger a = privateKey.getLambda();

assertEquals(e, a);
}

@Test
public void computationOfG() throws Exception {
prepareTest();

PowerMockito.verifyNew(BigInteger.class, Mockito.times(2)).withArguments(Mockito.eq(128), Mockito.any(Random.class));
}

@Test
public void withoutCertainty() throws Exception {
prepareTest();

PowerMockito.verifyStatic(Mockito.times(2));
BigInteger.probablePrime(BITS / 2, rng);

}

@Test
public void withCertainty() throws Exception {
int certainty = 6;

keygen.certainty(certainty);

PowerMockito.whenNew(BigInteger.class).withArguments(BITS / 2, certainty, rng).thenReturn(p, q);

prepareTest();

PowerMockito.verifyNew(BigInteger.class, Mockito.times(2)).withArguments(BITS / 2, certainty, rng);
}

}

+ 0
- 124
source/crypto/crypto-adv/src/test/java/test/com/jd/blockchain/crypto/paillier/ResolveTest.java View File

@@ -1,124 +0,0 @@
package test.com.jd.blockchain.crypto.paillier;

import com.jd.blockchain.crypto.paillier.*;
import org.junit.Test;

import java.math.BigInteger;

import static org.junit.Assert.assertEquals;

public class ResolveTest {

@Test
public void testResolvePrivateKey() {
KeyPairBuilder keygen = new KeyPairBuilder();
KeyPair keyPair = keygen.generateKeyPair();

PrivateKey privKey = keyPair.getPrivateKey();
BigInteger lambda = privKey.getLambda();
BigInteger preCalculatedDenominator = privKey.getPreCalculatedDenominator();

byte[] privKeyBytes = privKey.getPrivKeyBytes();
byte[] lambdaBytes = privKey.getLambdaBytes();
byte[] preCalculatedDenominatorBytes = privKey.getPreCalculatedDenominatorBytes();

assertEquals(lambda,new BigInteger(lambdaBytes));
assertEquals(preCalculatedDenominator,new BigInteger(preCalculatedDenominatorBytes));

assertEquals(lambda,new PrivateKey(lambda,preCalculatedDenominator).getLambda());
assertEquals(preCalculatedDenominator,(new PrivateKey(lambda,preCalculatedDenominator)).getPreCalculatedDenominator());

assertEquals(lambda,(new PrivateKey(lambdaBytes,preCalculatedDenominatorBytes)).getLambda());
assertEquals(preCalculatedDenominator,(new PrivateKey(lambdaBytes,preCalculatedDenominatorBytes)).getPreCalculatedDenominator());

assertEquals(lambda,(new PrivateKey(privKeyBytes)).getLambda());
assertEquals(preCalculatedDenominator,(new PrivateKey(privKeyBytes)).getPreCalculatedDenominator());
}

@Test
public void testResolvePublicKey() {
KeyPairBuilder keygen = new KeyPairBuilder();
KeyPair keyPair = keygen.generateKeyPair();

PublicKey pubKey = keyPair.getPublicKey();
int bits = pubKey.getBits();
BigInteger n = pubKey.getN();
BigInteger nSquared = pubKey.getnSquared();
BigInteger g = pubKey.getG();

byte[] pubKeyBytes = pubKey.getPubKeyBytes();
byte[] bitsBytes = pubKey.getBitsBytes();
byte[] nBytes = pubKey.getNBytes();
byte[] nSquaredBytes = pubKey.getNSquaredBytes();
byte[] gBytes = pubKey.getGBytes();

assertEquals(bits,PaillierUtils.bytesToInt(bitsBytes));
assertEquals(n,new BigInteger(nBytes));
assertEquals(nSquared,new BigInteger(nSquaredBytes));
assertEquals(g,new BigInteger(gBytes));

assertEquals(bits,(new PublicKey(n,nSquared,g,bits)).getBits());
assertEquals(n,(new PublicKey(n,nSquared,g,bits)).getN());
assertEquals(nSquared,(new PublicKey(n,nSquared,g,bits)).getnSquared());
assertEquals(g,(new PublicKey(n,nSquared,g,bits)).getG());

assertEquals(bits,(new PublicKey(nBytes,nSquaredBytes,gBytes,bitsBytes)).getBits());
assertEquals(n,(new PublicKey(nBytes,nSquaredBytes,gBytes,bitsBytes)).getN());
assertEquals(nSquared,(new PublicKey(nBytes,nSquaredBytes,gBytes,bitsBytes)).getnSquared());
assertEquals(g,(new PublicKey(nBytes,nSquaredBytes,gBytes,bitsBytes)).getG());

assertEquals(bits,(new PublicKey(pubKeyBytes)).getBits());
assertEquals(n,(new PublicKey(pubKeyBytes)).getN());
assertEquals(nSquared,(new PublicKey(pubKeyBytes)).getnSquared());
assertEquals(g,(new PublicKey(pubKeyBytes)).getG());
}

@Test
public void testResolveKeyPair() {
KeyPairBuilder keygen = new KeyPairBuilder();
keygen.upperBound(new BigInteger(PaillierUtils.intToBytes(Integer.MAX_VALUE)));
KeyPair keyPair = keygen.generateKeyPair();

PrivateKey privKey = keyPair.getPrivateKey();
PublicKey pubKey = keyPair.getPublicKey();
BigInteger upperBound = keyPair.getUpperBound();

byte[] keyPairBytes = keyPair.getKeyPairBytes();
byte[] privKeyBytes = privKey.getPrivKeyBytes();
byte[] pubKeyBytes = pubKey.getPubKeyBytes();
byte[] upperBoundBytes = keyPair.getUpperBoundBytes();

assertEquals(upperBound,keyPair.getUpperBound());
assertEquals(privKey.getLambda(),keyPair.getPrivateKey().getLambda());
assertEquals(privKey.getPreCalculatedDenominator(),keyPair.getPrivateKey().getPreCalculatedDenominator());
assertEquals(pubKey.getBits(),keyPair.getPublicKey().getBits());
assertEquals(pubKey.getN(),keyPair.getPublicKey().getN());
assertEquals(pubKey.getnSquared(),keyPair.getPublicKey().getnSquared());
assertEquals(pubKey.getG(),keyPair.getPublicKey().getG());

assertEquals(upperBound,(new KeyPair(privKey,pubKey,upperBound).getUpperBound()));
assertEquals(privKey.getLambda(),(new KeyPair(privKey,pubKey,upperBound).getPrivateKey().getLambda()));
assertEquals(privKey.getPreCalculatedDenominator(),(new KeyPair(privKey,pubKey,upperBound).getPrivateKey().getPreCalculatedDenominator()));
assertEquals(pubKey.getBits(),(new KeyPair(privKey,pubKey,upperBound).getPublicKey().getBits()));
assertEquals(pubKey.getN(),(new KeyPair(privKey,pubKey,upperBound).getPublicKey().getN()));
assertEquals(pubKey.getnSquared(),(new KeyPair(privKey,pubKey,upperBound).getPublicKey().getnSquared()));
assertEquals(pubKey.getG(),(new KeyPair(privKey,pubKey,upperBound).getPublicKey().getG()));

assertEquals(upperBound,(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getUpperBound()));
assertEquals(privKey.getLambda(),(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getPrivateKey().getLambda()));
assertEquals(privKey.getPreCalculatedDenominator(),(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getPrivateKey().getPreCalculatedDenominator()));
assertEquals(pubKey.getBits(),(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getPublicKey().getBits()));
assertEquals(pubKey.getN(),(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getPublicKey().getN()));
assertEquals(pubKey.getnSquared(),(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getPublicKey().getnSquared()));
assertEquals(pubKey.getG(),(new KeyPair(privKeyBytes,pubKeyBytes,upperBoundBytes).getPublicKey().getG()));

assertEquals(upperBound,(new KeyPair(keyPairBytes).getUpperBound()));
assertEquals(privKey.getLambda(),(new KeyPair(keyPairBytes).getPrivateKey().getLambda()));
assertEquals(privKey.getPreCalculatedDenominator(),(new KeyPair(keyPairBytes).getPrivateKey().getPreCalculatedDenominator()));
assertEquals(pubKey.getBits(),(new KeyPair(keyPairBytes).getPublicKey().getBits()));
assertEquals(pubKey.getN(),(new KeyPair(keyPairBytes).getPublicKey().getN()));
assertEquals(pubKey.getnSquared(),(new KeyPair(keyPairBytes).getPublicKey().getnSquared()));
assertEquals(pubKey.getG(),(new KeyPair(keyPairBytes).getPublicKey().getG()));

}
}

Loading…
Cancel
Save