2016-04-22 11 views
-2

私はpaillier暗号を使って2つの数字を暗号化しています。数字の暗号化された値はbigIntegerです。値を小数にする場合 たとえば、9の最初の暗号化値は12446486760457687016046 であり、暗号化された値3は98647617673416817617です。除算の結果は小数である可能性があります。 paillierはbigIntegerをパラメータとして取得するため、最終結果は0です。どうやって分けることができますか?パイヤ暗号で2つの数を分割する方法は?

public class Paillier { 

/** 
* p and q are two large primes. 
* lambda = lcm(p-1, q-1) = (p-1)*(q-1)/gcd(p-1, q-1). 
*/ 
private BigInteger p, q, lambda; 
/** 
* n = p*q, where p and q are two large primes. 
*/ 
public BigInteger n; 
/** 
* nsquare = n*n 
*/ 
public BigInteger nsquare; 
/** 
* a random integer in Z*_{n^2} where gcd (L(g^lambda mod n^2), n) = 1. 
*/ 
private BigInteger g; 
/** 
* number of bits of modulus 
*/ 
private int bitLength; 

/** 
* Constructs an instance of the Paillier cryptosystem. 
* @param bitLengthVal number of bits of modulus 
* @param certainty The probability that the new BigInteger represents a prime number will exceed (1 - 2^(-certainty)). The execution time of this constructor is proportional to the value of this parameter. 
*/ 
public Paillier(int bitLengthVal, int certainty) { 
KeyGeneration(bitLengthVal, certainty); 
} 

/** 
* Constructs an instance of the Paillier cryptosystem with 512 bits of modulus and at least 1-2^(-64) certainty of primes generation. 
*/ 
public Paillier() { 
KeyGeneration(512, 64); 
} 

/** 
* Sets up the public key and private key. 
* @param bitLengthVal number of bits of modulus. 
* @param certainty The probability that the new BigInteger represents a prime number will exceed (1 - 2^(-certainty)). The execution time of this constructor is proportional to the value of this parameter. 
*/ 
public void KeyGeneration(int bitLengthVal, int certainty) { 
bitLength = bitLengthVal; 
/*Constructs two randomly generated positive BigIntegers that are probably prime, with the specified bitLength and certainty.*/ 
p = new BigInteger(bitLength/2, certainty, new Random()); 
q = new BigInteger(bitLength/2, certainty, new Random()); 

n = p.multiply(q); 
nsquare = n.multiply(n); 

g = new BigInteger("2"); 
lambda = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)).divide(
p.subtract(BigInteger.ONE).gcd(q.subtract(BigInteger.ONE))); 
/* check whether g is good.*/ 
if (g.modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(n).gcd(n).intValue() != 1) { 
System.out.println("g is not good. Choose g again."); 
System.exit(1); 
} 
} 

/** 
* Encrypts plaintext m. ciphertext c = g^m * r^n mod n^2. This function explicitly requires random input r to help with encryption. 
* @param m plaintext as a BigInteger 
* @param r random plaintext to help with encryption 
* @return ciphertext as a BigInteger 
*/ 
public BigInteger Encryption(BigInteger m, BigInteger r) { 
return g.modPow(m, nsquare).multiply(r.modPow(n, nsquare)).mod(nsquare); 
} 

/** 
* Encrypts plaintext m. ciphertext c = g^m * r^n mod n^2. This function automatically generates random input r (to help with encryption). 
* @param m plaintext as a BigInteger 
* @return ciphertext as a BigInteger 
*/ 
public BigInteger Encryption(BigInteger m) { 
BigInteger r = new BigInteger(bitLength, new Random()); 
return g.modPow(m, nsquare).multiply(r.modPow(n, nsquare)).mod(nsquare); 

} 

/** 
* Decrypts ciphertext c. plaintext m = L(c^lambda mod n^2) * u mod n, where u = (L(g^lambda mod n^2))^(-1) mod n. 
* @param c ciphertext as a BigInteger 
* @return plaintext as a BigInteger 
*/ 
public BigInteger Decryption(BigInteger c) { 
BigInteger u = g.modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(n).modInverse(n); 
return c.modPow(lambda, nsquare).subtract(BigInteger.ONE).divide(n).multiply(u).mod(n); 
} 

/** 
* main function 
* @param str intput string 
*/ 
public static void main(String[] str) { 
/* instantiating an object of Paillier cryptosystem*/ 
Paillier paillier = new Paillier(); 
BigInteger o1 = (paillier.Encryption(new BigInteger("9"))); 
BigInteger o2 = (paillier.Encryption(new BigInteger("3"))); 
BigInteger od = o2.divide(o1); 
System.out.println(paillier.Decryption(od)); 
+0

この回答は、http://crypto.stackexchange.com/questions/2076/division-in-paillier-cryptosystemの洞察を提供します。少なくともその最初の3語。 – JulienD

+0

数字の暗号化表現を分割したいだけですか?どのようにして1つのBigIntを別のものに分けるのですか? –

+0

@ Eric J.これは準同型の暗号化です。「暗号化された引数を追加した結果、復号化された元の数の合計」のようなものです。しかし、この方法では、明らかに分裂のために保持されません。 – JulienD

答えて

0

暗号アプリケーションでI explained before,ように、除算の代わりに、逆数を使用することが一般的です。少し後、私はは、除数の逆数でを乗算することと同じことをするだろうことを知った9÷3 = 3:9×⅓= 3小学校で

、私は3で9を分割することを学びました有理数の1/3は、の乗法逆数であり、3:3×1/3 = 1のです。

モジュラ演算では、乗法逆数は逆数に似ています。 256を法とする数を扱っていると仮定します。私は3で除算したいと思います。上記のように、私は「除数」の乗法逆数を使ってそれを行うことができます。 3×171 mod 256 = 1なので、171は3の逆数です。しかし、9×171 = 1539を待ってください。3ではないでしょうか?ああ、お待ちください。モジュロ256:1539 mod 256 = 3を使用していることを忘れてしまいました。

例では、係数として使用できる2つの数値、nまたはnsquareがあります。もしあなたがstudy a bit,なら、あなたはPaillierと準同型の算術演算を実行するときに使うべきものを発見するでしょう。次に、modInverse()関数を使用して "減算"を実行することができます。

Paillier paillier = new Paillier(); 
BigInteger o1 = (paillier.Encryption(new BigInteger("9"))); 
BigInteger o2 = (paillier.Encryption(new BigInteger("3"))); 
BigInteger od = o1.multiply(o2.modInverse(???)); 
System.out.println(paillier.Decryption(od)); 
+0

ありがとうございます。それは働いた:) –

+0

paillierの暗号システムで2つの暗号化された数を分割することは可能ですか? [A]と[B]があり、A/Bを計算したいとします。これはまったく可能ですか? –

+0

@Nooshinsalekfaramarziはい。上記の例は、A = 9とB = 3の場合を示しています。 – erickson

関連する問題