gpt4 book ai didi

Shamir的 secret 分享的Java实现

转载 作者:搜寻专家 更新时间:2023-10-31 19:28:37 25 4
gpt4 key购买 nike

我尝试用 Java 实现 Shamir 的 secret 共享,但我遇到了一些问题。

当我将 K>10 时, secret 不再被重建。谁能帮我?这就是我所做的。有什么问题?

最初我选择 N 和 K,接下来是系数的生成、共享的创建,最后是重构。

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


public class Main {
public static void main(String[] args){

//INIT
int N = 55;
int K = 11;

BigInteger secret = new BigInteger("123");
modLength = secret.bitLength() + 1;
BigInteger primeNum = genPrime();
BigInteger[] coeff = new BigInteger[K-1];
BigInteger[] partecipants = new BigInteger[K];
for (int i=0;i<K;i++)
partecipants[i] = new BigInteger(Integer.toString(i+1));
System.out.println("Prime Number: "+primeNum);
for (int i=0;i<K-1;i++){
coeff[i] = randomZp(primeNum);
System.out.println("a"+(i+1)+": "+coeff[i]);
}

//SHARES
BigInteger[] shares = new BigInteger[N];
for(int i=0;i<N;i++){
BigInteger toAdd= secret;
for(int j=0;j<K-1;j++){
BigInteger power = new BigInteger(Integer.toString((int)(Math.pow((i+1),(j+1)))));
toAdd=toAdd.add(coeff[j].multiply(power));
}
shares[i] = toAdd.mod(primeNum);
System.out.println("Share n."+(i+1)+": "+shares[i]);
}
//INTERPOLAZIONE
BigInteger secret2= new BigInteger("0");
double term;
for (int i=0;i<K;i++){
term = 1;
BigInteger sharePartecipanteNow = shares[(partecipants[i].intValue())-1];
for (int j=0;j<K;j++){
if (partecipants[i].intValue()!=partecipants[j].intValue()){

BigInteger num = new BigInteger(Integer.toString(partecipants[j].intValue()*(-1)));
BigInteger den = new BigInteger(Integer.toString(partecipants[i].intValue()-partecipants[j].intValue()));
term = term*(num.doubleValue())/(den.doubleValue());
}

}
term = term*sharePartecipanteNow.intValue();
secret2 = secret2.add(new BigInteger(Integer.toString((int)term)));
}
while(secret2.intValue()<0)
secret2 = secret2.add(primeNum);
System.out.println("The secret is: "+secret2.mod(primeNum));
}

private static BigInteger genPrime() {
BigInteger p=null;
boolean ok=false;
do{
p=BigInteger.probablePrime(modLength, new Random());
if(p.isProbablePrime(CERTAINTY))
ok=true;
}while(ok==false);
return p;
}

private static BigInteger randomZp(BigInteger p) {
BigInteger r;
do{
r = new BigInteger(modLength, new Random());
} while (r.compareTo(BigInteger.ZERO) < 0 || r.compareTo(p) >= 0);
return r;
}

private static final int CERTAINTY = 50;
private static int modLength;
}

最佳答案

karbi79 的 Shamir 的 secret 共享实现无效。 答案可能看起来不错 [基本测试工作正常],但事实并非如此!

正确实现 Shamir Secret Sharing 让我成为 friend 。这是他的代码:

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

public final class Shamir
{
public static SecretShare[] split(final BigInteger secret, int needed, int available, BigInteger prime, Random random)
{
System.out.println("Prime Number: " + prime);

final BigInteger[] coeff = new BigInteger[needed];
coeff[0] = secret;
for (int i = 1; i < needed; i++)
{
BigInteger r;
while (true)
{
r = new BigInteger(prime.bitLength(), random);
if (r.compareTo(BigInteger.ZERO) > 0 && r.compareTo(prime) < 0)
{
break;
}
}
coeff[i] = r;
}

final SecretShare[] shares = new SecretShare[available];
for (int x = 1; x <= available; x++)
{
BigInteger accum = secret;

for (int exp = 1; exp < needed; exp++)
{
accum = accum.add(coeff[exp].multiply(BigInteger.valueOf(x).pow(exp).mod(prime))).mod(prime);
}
shares[x - 1] = new SecretShare(x, accum);
System.out.println("Share " + shares[x - 1]);
}

return shares;
}

public static BigInteger combine(final SecretShare[] shares, final BigInteger prime)
{
BigInteger accum = BigInteger.ZERO;

for(int formula = 0; formula < shares.length; formula++)
{
BigInteger numerator = BigInteger.ONE;
BigInteger denominator = BigInteger.ONE;

for(int count = 0; count < shares.length; count++)
{
if(formula == count)
continue; // If not the same value

int startposition = shares[formula].getNumber();
int nextposition = shares[count].getNumber();

numerator = numerator.multiply(BigInteger.valueOf(nextposition).negate()).mod(prime); // (numerator * -nextposition) % prime;
denominator = denominator.multiply(BigInteger.valueOf(startposition - nextposition)).mod(prime); // (denominator * (startposition - nextposition)) % prime;
}
BigInteger value = shares[formula].getShare();
BigInteger tmp = value.multiply(numerator) . multiply(modInverse(denominator, prime));
accum = prime.add(accum).add(tmp) . mod(prime); // (prime + accum + (value * numerator * modInverse(denominator))) % prime;
}

System.out.println("The secret is: " + accum + "\n");

return accum;
}

private static BigInteger[] gcdD(BigInteger a, BigInteger b)
{
if (b.compareTo(BigInteger.ZERO) == 0)
return new BigInteger[] {a, BigInteger.ONE, BigInteger.ZERO};
else
{
BigInteger n = a.divide(b);
BigInteger c = a.mod(b);
BigInteger[] r = gcdD(b, c);
return new BigInteger[] {r[0], r[2], r[1].subtract(r[2].multiply(n))};
}
}

private static BigInteger modInverse(BigInteger k, BigInteger prime)
{
k = k.mod(prime);
BigInteger r = (k.compareTo(BigInteger.ZERO) == -1) ? (gcdD(prime, k.negate())[2]).negate() : gcdD(prime,k)[2];
return prime.add(r).mod(prime);
}

public static void main(final String[] args)
{
final int CERTAINTY = 256;
final SecureRandom random = new SecureRandom();

final BigInteger secret = new BigInteger("123");

// prime number must be longer then secret number
final BigInteger prime = new BigInteger(secret.bitLength() + 1, CERTAINTY, random);

// 2 - at least 2 secret parts are needed to view secret
// 5 - there are 5 persons that get secret parts
final SecretShare[] shares = Shamir.split(secret, 2, 5, prime, random);


// we can use any combination of 2 or more parts of secret
SecretShare[] sharesToViewSecret = new SecretShare[] {shares[0],shares[1]}; // 0 & 1
BigInteger result = Shamir.combine(sharesToViewSecret, prime);

sharesToViewSecret = new SecretShare[] {shares[1],shares[4]}; // 1 & 4
result = Shamir.combine(sharesToViewSecret, prime);

sharesToViewSecret = new SecretShare[] {shares[0],shares[1],shares[3]}; // 0 & 1 & 3
result = Shamir.combine(sharesToViewSecret, prime);
}
}

SecretShare.java:

import java.math.BigInteger;

public class SecretShare
{
public SecretShare(final int number, final BigInteger share)
{
this.number = number;
this.share = share;
}

public int getNumber()
{
return number;
}

public BigInteger getShare()
{
return share;
}

@Override
public String toString()
{
return "SecretShare [num=" + number + ", share=" + share + "]";
}

private final int number;
private final BigInteger share;
}

关于Shamir的 secret 分享的Java实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19327651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com