@@ -1,4 +1,16 @@
package cn.hutool.crypto.asymmetric ;
/ *
* Copyright ( c ) 2023 looly ( loolly @aliyun.com )
* Hutool is licensed under Mulan PSL v2 .
* You can use this software according to the terms and conditions of the Mulan PSL v2 .
* You may obtain a copy of Mulan PSL v2 at :
* http : / / license . coscl . org . cn / MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN " AS IS " BASIS , WITHOUT WARRANTIES OF ANY KIND ,
* EITHER EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO NON - INFRINGEMENT ,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE .
* See the Mulan PSL v2 for more details .
* /
package cn.hutool.crypto.asymmetric.paillier ;
import cn.hutool.core.util.HexUtil ;
@@ -8,16 +20,16 @@ import java.util.Random;
/ * *
* 同态加密算法Paillier
*
* < p >
* 加法同态 , 存在有效算法 + , E ( x + y ) = E ( x ) + E ( y ) 或者 x + y = D ( E ( x ) + E ( y ) ) 成立 , 并且不泄漏 x 和 y 。
* 乘法同态 , 存在有效算法 * , E ( x × y ) = E ( x ) * E ( y ) 或者 xy = D ( E ( x ) * E ( y ) ) 成立 , 并且不泄漏 x 和 y 。
*
* < p >
* 方案安全性可以归约到判定性合数剩余假设 ( Decisional Composite Residuosity Assumption , DCRA ) , 即给定一个合数n和整数z , 判定z是否在n ^ 2下是否是n次剩余是困难的 。
* 这个假设经过了几十年的充分研究 , 到目前为止还没有多项式时间的算法可以攻破 , 所以Paillier加密方案的安全性被认为相当可靠 。
*
* < p >
* 字符串文本加解密相互配对 , 此时无法使用同态加法和同态乘法
* 数值类型不可使用字符串加解密
*
* < p >
* 公钥加密和同态加法 / 同态乘法运算
* 私钥解密
*
@@ -27,14 +39,14 @@ public class Paillier {
/ / 公钥 n g
/ / 私钥 n lambda u
private static int bitLength = 2048 ;
private static int certainty = 256 ;
private static final int bitLength = 2048 ;
private static final int certainty = 256 ;
/ * *
* 生成密钥算法 。 ( 默认 )
* @return PaillierKeyPair 公钥私钥对
* /
public static final PaillierKeyPair generateKey ( ) {
public static PaillierKeyPair generateKey ( ) {
return generateKey ( bitLength , certainty ) ;
}
@@ -45,19 +57,18 @@ public class Paillier {
* @param certainty 此构造函数的执行时间与此参数的值成比例 。
* @return PaillierKeyPair 公钥私钥对
* /
public static final PaillierKeyPair generateKey ( int bitLength , int certainty ) {
BigInteger p = new BigInteger ( bitLength / 2 , certainty , new SecureRandom ( ) ) ;
BigInteger q = new BigInteger ( bitLength / 2 , certainty , new SecureRandom ( ) ) ;
BigInteger n = p . multiply ( q ) ;
BigInteger nSquare = n . multiply ( n ) ;
BigInteger lambda = p . subtract ( BigInteger . ONE ) . multiply ( q . subtract ( BigInteger . ONE ) )
public static PaillierKeyPair generateKey ( final int bitLength , final int certainty ) {
final BigInteger p = new BigInteger ( bitLength / 2 , certainty , new SecureRandom ( ) ) ;
final BigInteger q = new BigInteger ( bitLength / 2 , certainty , new SecureRandom ( ) ) ;
final BigInteger n = p . multiply ( q ) ;
final BigInteger nSquare = n . multiply ( n ) ;
final BigInteger lambda = p . subtract ( BigInteger . ONE ) . multiply ( q . subtract ( BigInteger . ONE ) )
. divide ( p . subtract ( BigInteger . ONE ) . gcd ( q . subtract ( BigInteger . ONE ) ) ) ;
BigInteger g = n . add ( BigInteger . ONE ) ;
BigInteger u = g . modPow ( lambda , nSquare ) . subtract ( BigInteger . ONE ) . divide ( n ) . modInverse ( n ) ;
PaillierpublicKey publicKey = new PaillierpublicKey ( n , g ) ;
PaillierPrivateKey privateKey = new PaillierPrivateKey ( n , lambda , u ) ;
PaillierKeyPair keyPair = new PaillierKeyPair ( publicKey , privateKey ) ;
return keyPair ;
final BigInteger g = n . add ( BigInteger . ONE ) ;
final BigInteger u = g . modPow ( lambda , nSquare ) . subtract ( BigInteger . ONE ) . divide ( n ) . modInverse ( n ) ;
final PaillierpublicKey publicKey = new PaillierpublicKey ( n , g ) ;
final PaillierPrivateKey privateKey = new PaillierPrivateKey ( n , lambda , u ) ;
return new PaillierKeyPair ( publicKey , privateKey ) ;
}
/ * *
@@ -69,10 +80,10 @@ public class Paillier {
*
* @return byte [ ] 密文
* /
public static final byte [ ] encryptString ( String text , PaillierpublicKey publicKey ) {
BigInteger r = new BigInteger ( bitLength , new Random ( ) ) ;
BigInteger n = publicKey . getN ( ) ;
BigInteger nsquare = n . multiply ( n ) ;
public static byte [ ] encryptString ( final String text , final PaillierpublicKey publicKey ) {
final BigInteger r = new BigInteger ( bitLength , new Random ( ) ) ;
final BigInteger n = publicKey . getN ( ) ;
final BigInteger nsquare = n . multiply ( n ) ;
return publicKey . getG ( ) . modPow ( new BigInteger ( HexUtil . encodeHexStr ( text ) , 16 ) , nsquare ) . multiply ( r . modPow ( n , nsquare ) ) . mod ( nsquare ) . toByteArray ( ) ;
}
@@ -83,12 +94,12 @@ public class Paillier {
* @param privateKey 私钥
* @return 解密的明文
* /
public static final String decryptString ( byte [ ] ciphertext , PaillierPrivateKey privateKey ) {
BigInteger n = privateKey . getN ( ) ;
BigInteger lambda = privateKey . getLambda ( ) ;
BigInteger u = privateKey . getu ( ) ;
BigInteger nsquare = n . multiply ( n ) ;
String s = new BigInteger ( ciphertext ) . modPow ( lambda , nsquare ) . subtract ( BigInteger . ONE ) . divide ( n ) . multiply ( u ) . mod ( n ) . toString ( ) ;
public static String decryptString ( final byte [ ] ciphertext , final PaillierPrivateKey privateKey ) {
final BigInteger n = privateKey . getN ( ) ;
final BigInteger lambda = privateKey . getLambda ( ) ;
final BigInteger u = privateKey . getu ( ) ;
final BigInteger nsquare = n . multiply ( n ) ;
final String s = new BigInteger ( ciphertext ) . modPow ( lambda , nsquare ) . subtract ( BigInteger . ONE ) . divide ( n ) . multiply ( u ) . mod ( n ) . toString ( ) ;
return HexUtil . decodeHexStr ( new BigInteger ( s ) . toString ( 16 ) ) ;
}
@@ -99,10 +110,10 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] encrypt ( BigInteger text , PaillierpublicKey publicKey ) {
BigInteger r = new BigInteger ( bitLength , new Random ( ) ) ;
BigInteger n = publicKey . getN ( ) ;
BigInteger nsquare = n . multiply ( n ) ;
public static byte [ ] encrypt ( final BigInteger text , final PaillierpublicKey publicKey ) {
final BigInteger r = new BigInteger ( bitLength , new Random ( ) ) ;
final BigInteger n = publicKey . getN ( ) ;
final BigInteger nsquare = n . multiply ( n ) ;
return publicKey . getG ( ) . modPow ( text , nsquare ) . multiply ( r . modPow ( n , nsquare ) ) . mod ( nsquare ) . toByteArray ( ) ;
}
@@ -113,11 +124,11 @@ public class Paillier {
* @param privateKey 私钥
* @return 解密的明文
* /
public static final String decrypt ( byte [ ] ciphertext , PaillierPrivateKey privateKey ) {
BigInteger n = privateKey . getN ( ) ;
BigInteger lambda = privateKey . getLambda ( ) ;
BigInteger u = privateKey . getu ( ) ;
BigInteger nsquare = n . multiply ( n ) ;
public static String decrypt ( final byte [ ] ciphertext , final PaillierPrivateKey privateKey ) {
final BigInteger n = privateKey . getN ( ) ;
final BigInteger lambda = privateKey . getLambda ( ) ;
final BigInteger u = privateKey . getu ( ) ;
final BigInteger nsquare = n . multiply ( n ) ;
return new BigInteger ( ciphertext ) . modPow ( lambda , nsquare ) . subtract ( BigInteger . ONE ) . divide ( n ) . multiply ( u ) . mod ( n ) . toString ( ) ;
}
@@ -129,7 +140,7 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] add ( BigInteger ciphertext , BigInteger ciphertext2 , PaillierpublicKey publicKey ) {
public static byte [ ] add ( final BigInteger ciphertext , final BigInteger ciphertext2 , final PaillierpublicKey publicKey ) {
return ciphertext . add ( ciphertext2 ) . multiply ( publicKey . getN ( ) ) . toByteArray ( ) ;
}
@@ -141,7 +152,7 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] add ( String ciphertext , String ciphertext2 , PaillierpublicKey publicKey ) {
public static byte [ ] add ( final String ciphertext , final String ciphertext2 , final PaillierpublicKey publicKey ) {
return new BigInteger ( ciphertext ) . multiply ( new BigInteger ( ciphertext2 ) ) . mod ( publicKey . getN ( ) . multiply ( publicKey . getN ( ) ) ) . toByteArray ( ) ;
}
@@ -153,7 +164,7 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] add ( byte [ ] ciphertext , byte [ ] ciphertext2 , PaillierpublicKey publicKey ) {
public static byte [ ] add ( final byte [ ] ciphertext , final byte [ ] ciphertext2 , final PaillierpublicKey publicKey ) {
return new BigInteger ( ciphertext ) . multiply ( new BigInteger ( ciphertext2 ) ) . mod ( publicKey . getN ( ) . multiply ( publicKey . getN ( ) ) ) . toByteArray ( ) ;
}
@@ -165,7 +176,7 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] multiply ( BigInteger ciphertext , BigInteger number , PaillierpublicKey publicKey ) {
public static byte [ ] multiply ( final BigInteger ciphertext , final BigInteger number , final PaillierpublicKey publicKey ) {
return ciphertext . modPow ( number , publicKey . getN ( ) . multiply ( publicKey . getN ( ) ) ) . toByteArray ( ) ;
}
@@ -177,7 +188,7 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] multiply ( String ciphertext , BigInteger number , PaillierpublicKey publicKey ) {
public static byte [ ] multiply ( final String ciphertext , final BigInteger number , final PaillierpublicKey publicKey ) {
return new BigInteger ( ciphertext ) . modPow ( number , publicKey . getN ( ) . multiply ( publicKey . getN ( ) ) ) . toByteArray ( ) ;
}
@@ -189,7 +200,7 @@ public class Paillier {
* @param publicKey 公钥
* @return byte [ ] 密文
* /
public static final byte [ ] multiply ( byte [ ] ciphertext , BigInteger number , PaillierpublicKey publicKey ) {
public static byte [ ] multiply ( final byte [ ] ciphertext , final BigInteger number , final PaillierpublicKey publicKey ) {
return new BigInteger ( ciphertext ) . modPow ( number , publicKey . getN ( ) . multiply ( publicKey . getN ( ) ) ) . toByteArray ( ) ;
}
}