如何在Shamir Secret Sharing

时间:2016-02-22 13:05:32

标签: java cryptography

我的大学有一个与Shamir Secret Sharing有关的学期项目。我的任务是实现一个代码,该代码可以将文件分成几部分然后重新构建。实际上,我已经实现了我的Shamir Secret Sharing代码,但我是在主要领域实现的。我的主管告诉我,我必须为扩展字段做。对于素数字段,我使用了BigInteger构造函数

final BigInteger prime = new BigInteger(secret.bitLength() + 1, CERTAINTY, random); 

我将非常感谢能够帮助我弄清楚如何修改扩展字段代码的人。我使用这个构造函数生成256(2pow8)

 String val="256";
 final BigInteger prime = new BigInteger(String val); 

我可以生成一个2的幂,但重建和生成股票的工作不正常。有什么建议吗?

我的代码是:

Shamir.java

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



// final class means we can not extend class Shamir
public final class Shamir
{
      //because of our shamir class is final  and can not be instantiated we need static methods to this class which can..
      // directly be accessed by shamir class without having to create a new object  


public static SecretShare[] ndarje(int k, int n,final BigInteger secret,  BigInteger prime, Random random)
{
 // parameters of the method which are going to take the arguments from the static main method
// variable int n is the number of all users which will receive the secret


 // variable int k is the number of participants needed to... 



            System.out.println("Prime Number: " + prime); // generation of prime number. We use BigInteger to generate it

              // a vector of type BigInteger named coeff of size n which will hold the coefficients of the polynom
              // construction of the polynom

              //the code from line 41 to 76 generate random number which will stay close to variable x of the polynom
              // for example f(x)= 120 + 123x + 13 xpow2 ; 120 , 123 and 13 are creating below till line 66 of code

        final BigInteger[] coeff = new BigInteger[n];

        coeff[0] = secret; // the first coefficient of polynom the one which is free is the secret  
        for (int i = 1; i < n; i++) // we start from 1 because f(0) iis the secret information
        {

    //  BigInteger b = new BigInteger(something here that can be match with BigInteger constructor) this create new reference

          BigInteger b ;
            //boolean isin=true;
            while (true) // go to an endless loop
            {

            // prime.bitLength() return number of bits in the minimal two's-complement representation of this BigInteger
           // also instances of the class can access methods ***
          // the constructor Constructs a randomly generated BigInteger, 
         //uniformly distributed over the range 0 to (2numBits - 1), inclusive

               b = new BigInteger(prime.bitLength(), random);

                 // b can be any number from 1 till p-1
                // compareTo is one of the method of BigInteger class
               // it Compares this BigInteger with the specified BigInteger.
              // Zero is the field of the BigInteger class and also an instance of this class which is accessed by operator .
             //  its value is 0
            // this comparison means that if our b is bigger than this BigInteger.Zero
           // the second comparison means that our r should be smaller than prime number

                if (b.compareTo(BigInteger.ZERO) > 0 && b.compareTo(prime) < 0)
                {
                   // isin=false;
                   break; // we need it to stop the endless loop if our condition upper are fulfilled
                      } // close if
                    } // close while
            coeff[i] = b; //pass this value to the vector which hold coeff
        } // close for loop

     // share the secret to the all participants each point of the polynom will go to one of them
     // create an array of type SecretShare of size n which will contain  all pair of shares
       final  SecretShare[] shares = new SecretShare[n];
        for (int x = 1; x <=n; x++) // loop till x=n , it will start from 1
        {
               // a0 which means the free variable of polynomial
            BigInteger a0= secret;

            for (int j = 1; j< k; j++) // loop till exp<k
            {
                      // add method of BigInteger public BigInteger add(BigInteger val)
                     // Returns a BigInteger whose value is (this + val) where this is value of secret = a0
                    //   polynom is in our case a0 + a1x+a2xpow2+...+a(k-1)pow(k-1) mod p where coeff[j]..
                   //   is the coeffiecent of x of our polynom
                  //   multiply method will Returns a BigInteger whose value is (this * val).
                 //   .valueof(x) method will return the value of x=(1,2,3...p-1)
                //     pow(j) will return the value of k (1,2,3...k-1)
               //    mod method will return a BigInteger whose value is (this mod prime).
              // in other words the statement below will compute polynom a0+a1x+a2xpow2+...+a(k-1)pow(k-1)

                a0= a0.add(coeff[j].multiply(BigInteger.valueOf(x).pow(j).mod(prime))).mod(prime);
            }

            shares[x-1] = new SecretShare(x, a0);
            System.out.println(shares[x-1]);
        }

        return shares; // return shares which must match with return type of the vector which is a array
    }   // close ndarje (name of my method) method


          // interpolation
         // second method 
    public static BigInteger kombinimi(final SecretShare[] shares, final BigInteger prime)
    {           
               // interpolation
              // new instance variables of this second method which its name is a0 and its value is zero

        BigInteger a0= BigInteger.ZERO;

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

            for(int j = 0; j< shares.length; j++)
            {
                if(i != j) {

                    //if(i != j) { } has the same function as we can write
                   // if (i==j) continue; 
                  // the meaning to both of them is :If not the same value

        // it is calling getNumber method which assign to int startposition value which is returned by getNumber method
       // so it will return numbers [1,2,3,4,5..,n]
      // one example a0=sum{(yi)product(xj/xj-xi)} for i=1 to number of needed client to reconstruct secret out of..
     // total number of clients. and i and j should not be the same to the production

                 // so this will take xi
                int startposition = shares[i].getNumber();

                // this will take xj
                int nextposition = shares[j].getNumber();

                 // so the steps now we need to do are.. After we take the values of xi [1,2,3,4..]
                // we need to calculate xj which below i called it numerator
               //and we also need to calculate xj-xi 

                   //negate and mod are also methods of Big Integer we need to use here

              numerator = numerator.multiply(BigInteger.valueOf(nextposition)).mod(prime); 
              // (numerator * nextposition) % prime;
              denominator = denominator.multiply(BigInteger.valueOf( nextposition - startposition)).mod(prime); 
              // (denominator * ( nextposition-startposition)) % prime;

            }  // close if
              } // close for

            // it is calling getShare method which assign to  BigInteger value  value which is returned by getShare method
           // so it will return yi

            BigInteger value = shares[i].getShare(); 

            // tmp will take lets say y1*[ x2*x3/(x2-x1)(x3-x1)]
           BigInteger tmp = value.multiply(numerator) . multiply(inv(denominator, prime));

           a0 = prime.add(a0).add(tmp) . mod(prime); 
           //  (prime + a+ (value * numerator * inv(denominator))) % prime;
        }

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

        return a0;

    }

       // method gcdD
    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))};
        } // close else
    } // close method

// this method is called to - multiply(modInverse(denominator, prime)) where denominator=k and prime=simplenumber
    private static BigInteger inv(BigInteger d, BigInteger simplenumber)
    { 
        d = d.mod(simplenumber);
 BigInteger r = (d.compareTo(BigInteger.ZERO) == -1) ? (gcdD(simplenumber, d.negate())[2]).negate() : gcdD(simplenumber,d)[2];
        return simplenumber.add(r).mod(simplenumber);
    } // close method

    public static void main(final String[] args)
    {
     // main method
    // its static method so we can access directly our static methods above by using name of the class

//use this BigInteger constructor - BigInteger(String val) which..
//Translates the decimal String representation of a BigInteger ("140") into a BigInteger.
          // so our secret number is 140
          // this is the way if we do not want to get secret from command line
    //   final BigInteger secret = new BigInteger("140");

 // take the argument from command line
  if (args.length < 3) {
 System.out.println("Dont forget to put k-number of clients needed to reconstruct the polynom");
  System.out.println("n-number of total clients ");
  System.out.println("And the third number is secret you want to deliver in this distributed system");
  System.out.println("first number you will put is k , second is n and third is secret");
 } else {

  // final int CERTAINTY = 256;

        final int numBits = 10;

    // SecureRandom class which is child of java.lang.Object , its constructor Constructs a secure random number generator
    // (RNG) implementing the default random number algorithm.

     final SecureRandom random = new SecureRandom();
 BigInteger secret=new BigInteger(args[2] );
  int k=Integer.parseInt(args[0] );
 int n=Integer.parseInt(args[1] );

final BigInteger prime= new BigInteger(numBits, random);

 // -----------------------------------------------------------------------------------------------------------------------------------------
          //Use BigInteger constructor-BigInteger(int bitLength, int certainty, Random rnd) which..
         //Constructs a randomly generated positive BigInteger that is probably prime, with the specified bitLength.
        // prime number must be longer then secret number

  //final BigInteger prime = new BigInteger(secret.bitLength() + 1, CERTAINTY, random);

// -----------------------------------------------------------------------------------------------------------------------------------------

       // k- at least k secret parts are needed to reconstruct the polynom
      // n- there are n persons that get secret parts
     // the order matters so we must write them (parameters) in order like the order of ndarje method

  final SecretShare[] s = Shamir.ndarje(k, n,secret, prime, random);

    //when use any combination of 2  parts of secret we will not get back our secret number we delivered to all participants
       SecretShare[] sharesToViewSecret = new SecretShare[] {s[2],s[1]}; // 0 & 1
      BigInteger result = Shamir.kombinimi(sharesToViewSecret, prime);


    //when use any combination of 2  parts of secret we will not get back our secret number(140) we delivered to all participants
       sharesToViewSecret = new SecretShare[] {s[0],s[1],s[2]}; // 1 & 4
      result = Shamir.kombinimi(sharesToViewSecret, prime);


    // here also    
        sharesToViewSecret = new SecretShare[] {s[5],s[1],s[3],s[4]}; // 0 & 1 & 3 & 4
       result = Shamir.kombinimi(sharesToViewSecret, prime);

  // but here we can get back our secret because the number of participants which reconstruct the polynom is >=6 , exactly 6 
       sharesToViewSecret = new SecretShare[] {s[2],s[1],s[3],s[4],s[6],s[10]}; // 0 & 1 & 3 & 4& 6 & 10
        result = Shamir.kombinimi(sharesToViewSecret, prime);

 // but here we can get back our secret because the number of participants which reconstruct the polynom is >=6 , exactly 7     
       sharesToViewSecret = new SecretShare[] {s[7],s[2],s[11],s[9],s[6],s[10],s[8]}; // 7 & 2 & 11 & 9 & 6 & 10 & 8
       result = Shamir.kombinimi(sharesToViewSecret, prime);
         }
    }
}

SecretShare.java

 import java.math.BigInteger;

public class SecretShare
{
       // instances

   private final int number;
    private final BigInteger share;


         // the constructor of the class

    public SecretShare(final int numri, final BigInteger shperndaje)
    {


        this.number = numri;
        this.share = shperndaje;
    }

       // getter methods

    public int getNumber()
    {
        return number;
    }
   // getter methods return share
    public BigInteger getShare()
    {
        return share;
    }



    @Override



    public String toString()
    {
           // String concatenation
        return "Secret which will share to all client is : [num=" + number + ", share=" + share +"]";
    }


}

0 个答案:

没有答案