online-casino.blog.ca

Blind signature Java code

Tuesday January 15th, 2013

Blind signature implementation in Java

Here is a client side code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package blindsignature;
 
import java.math.BigInteger;
import java.security.SecureRandom;
 
/**
 * VotingClient is a client-side of blind signature voting module. 
 * @author Pawel Maniora
 */
public class VotingClient {
 
   /**
   * number of candidates on voting cards
   */
    private int candidates;
 
   /**
   * numbers of cards - the higher amount - the safer and
   * slower voting is.
   */    
    private int cardamount;
 
   /**
   * public key encriptor. everybody who wants use it to encrypt message
   */
    private BigInteger e;
 
   /**
   * modulus used in encryption/decryption. everybody who wants use it 
   */
    private BigInteger mod;
 
   /**
   * all cards used to vote in plain format
   */
    private BigInteger[][] cards;
 
   /**
   * all blind cards
   */
    private BigInteger[][] encodedCards;
 
    /**
   * set of r. One r for each card used to make blinding factor
   */
    private BigInteger[] r;
 
   /**
   * set of inverted r used to remove blinding factor
   */
    private BigInteger[] rprim;
 
   /**
   * inverted r used to remove blinding factor from signed card
   * saved in another place than rprim set to send full rprim set to server
   */
    private BigInteger rfinal;
 
   /**
   * card signed by private key of server
   */
    private BigInteger[] signedCard;
 
   /**
   * voting client constructor
   */
   VotingClient(int candidates, int cardamount, BigInteger e, BigInteger mod){
        this.candidates = candidates;
        this.cardamount = cardamount;
        this.e = e;
        this.mod = mod;
        this.generateCards();
        this.generateBlindingFactors();
        this.generateUnblindingFactors();
        this.encodeCards();
        this.rfinal=null;
        this.signedCard=null;
    }
 
   /**
   * gemerate voting cards
   */    
    public final void generateCards(){
 
        cards = new BigInteger[cardamount][candidates];
 
        SecureRandom randomGenerator = new SecureRandom();
        for (int i = 1; i <= cardamount; ++i){
            //generate 9digit number
            int randomInt = randomGenerator.nextInt(899999999)+100000000;
            for (int j = 1; j <= candidates; ++j)
            { 
                cards[i-1][j-1]=new BigInteger(Integer.toString(j)+Integer.toString(randomInt));
               // System.out.println("Generated : " + j+randomInt);
            }
        }
 
    }
 
   /**
   * generate Blinding factor
   */     
    public final void generateBlindingFactors(){
 
     r = new BigInteger[cardamount];
 
     for (int i = 1; i <= cardamount; ++i){
 
         BigInteger rrand = null;
         BigInteger gcd = null;
         BigInteger one = new BigInteger("1");
 
         SecureRandom random = new SecureRandom();
 
 
         //check that gcd(r,n) = 1 && r < n && r > 1
         do {
             byte [] randomBytes = new byte[124];
             random.nextBytes(randomBytes);
             rrand = new BigInteger(1, randomBytes);
             gcd = rrand.gcd(mod);
             //System.out.println("gcd: " + gcd);
             r[i-1]=rrand;
         }
         while(!gcd.equals(one) || rrand.compareTo(mod)>=0 || rrand.compareTo(one)<=0);
     }
    }
 
   /**
   * create rprim from r
   */ 
    public final void generateUnblindingFactors(){
        rprim = new BigInteger[r.length];
 
         for (int i = 1; i <= r.length; ++i){
             rprim[i-1] = r[i-1].modInverse(mod);
         }
    }    
 
   /**
   * set final r and clear this r before send vector of requested r.
   */
    public void setRfinal(int norequest){
        if(rfinal==null && norequest>=0 && norequest <= candidates)
        {
        rfinal = rprim[norequest];
        rprim[norequest] = new BigInteger("0");
        } else System.out.println("ERROR: rfinal set before!");
    }
 
   /**
   * set signed card generated by VotingServer
   */   
    public void setSignedCard(BigInteger[] signedCard){
    this.signedCard = signedCard;
    }
 
 
   /**
   * send encodedCards to VotingServer
   */ 
    public final BigInteger[][] getCodedCards(){
    return encodedCards;
    }
 
   /**
   * send rprim to VotingServer
   */    
    public BigInteger[] getRprim(){
 
        //if rfinal != null means that rfinal is set and rprim is cleaned from rfinal
        if(rfinal!=null){
        return rprim;
        }else return null;
    }
 
   /**
   * encode cards to "codecards" for acceptable to send to VotingServer
   */ 
    public final void encodeCards(){
 
        encodedCards =new BigInteger[cardamount][candidates]; 
 
        for (int i = 1; i <= cardamount; ++i){
            for (int j = 1; j <= candidates; ++j)
            {   
                BigInteger re = r[i-1].modPow(e,mod);
                encodedCards[i-1][j-1]=cards[i-1][j-1].multiply(re).mod(mod);//multiply(re).mod(mod);
               // System.out.println("Generated : " + j+randomInt);
            }
        }
    }
 
    /**
   * remove rprim from signed card
   */    
    public void decodeCard(){
            for (int j = 1; j <= candidates; ++j)
            { 
                signedCard[j-1]=signedCard[j-1].multiply(rfinal).mod(mod);
            }
    }   
 
   /**
   * send vote to VotingServer
   * @param candidate   number of candidate on wchih you voting. 
   */ 
    public BigInteger sendVote(int candidate){
        if(signedCard!=null){ 
            decodeCard();
            return signedCard[candidate];
        }
        else return null;
    }
 
   /**
   * inform Voter if vote is accepted or not
   */     
    public void isVoteAccepted(boolean accepted){
        if(accepted){
            System.out.println("GLOS ZOSTAŁ DODANY");
        // add confirm information here
        } else {
        System.out.println("WYSTAPIL BLAD Z DODANIEM GLOSU!");
        //add reject information here
        }
    }
 
}

And here is a server side code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package blindsignature;
 
import java.math.BigInteger;
 
/**
 * VotingServer is a server-side of blind signature voting module. 
 * 
 * @author Pawel Maniora
 */
public class VotingServer {
 
   /**
   * number of candidates on voting cards
   */
    private int candidates;
 
   /**
   * numbers of cards - the higher amount - the safer and
   * slower voting is.
   */    
    private int cardamount;
 
   /**
   *  private key decriptor used to sign an decrypt votes
   */
    private BigInteger d;
 
   /**
   * public key encriptor. everybody who wants use it to encrypt message
   */
    public BigInteger e;
 
   /**
   * modulus used in encryption/decryption. everybody who wants use it 
   */
    public BigInteger mod;
 
   /**
   * number of voting card which is typed to not be checked and if everything
   * will be ok with others to be signed
   */
    public Integer norequest;
 
   /**
   * all coded cards sended from client
   */
    private BigInteger[][] codedcards;
 
/**
 * Voting Server constructor
 */        
    VotingServer(int candidates, int cardamount, BigInteger d, BigInteger e, BigInteger mod){
        this.candidates = candidates;
        this.cardamount = cardamount;
        this.d = d;
        this.e = e;
        this.mod = mod;
        this.norequest = null;
        this.codedcards = null;
    }
 
/**
 * Set Coded cards generated by client
 */     
    public void setCodedCards(BigInteger[][] codedcards)
    {
        if(this.codedcards==null)
        this.codedcards = codedcards;
    }
 
/**
 * Randomly choose @see #cardamount
 */         
   public int drawNoRequest(){
       if(norequest == null)
       norequest = (int)(Math.random()*(cardamount));
       return norequest;
   }
 
/**
 * The method check if format of cards are correct - if all without random one
 * are correct - it means that one left in very high probablility is also correct
 *
 * @param rprim - set of r^-1 mod(mod) used to unblind @see #codedcards
 */    
    public boolean checkCards( BigInteger[] rprim){
 
    String cardpattern ="";
 
    for (Integer i = 1; i <= cardamount; ++i){
        if(!i.equals(norequest+1)){
        for (int j = 1; j <= candidates; ++j)
            {  
               codedcards[i-1][j-1] = codedcards[i-1][j-1].modPow(d,mod).multiply(rprim[i-1]).mod(mod).modPow(e, mod);//multiply(rprimd).mod(mod); 
               String cleancard =  codedcards[i-1][j-1].toString();
 
               //check if votes have correct length 
               if(cleancard.length()!=10){
                   System.out.println("WRONG! CARD LENGTH!"); 
                   return false;
               }
 
               //card pattern to check if every vote on votingcard has the same number  
                if (j==1) cardpattern = cleancard.substring(1);
 
               String cardnumber = cleancard.substring(1);
               if(cardnumber.compareTo(cardpattern)!=0){
                   System.out.println("WRONG! NOT EQUAL NUMBERS!"); 
                   return false;
               }
 
               //check if on cards have correct candidates
               String cand = Character.toString(cleancard.charAt(0)); //candidate number
               if(Integer.toString(j).compareTo(cand)!=0){
                    System.out.println("WRONG BAD CANDIDATE NUMBER!");
                    return false;
               }
            } 
        }
 
    }
     return true;
    }
 
/**
 * Sign card using blind vote
 */      
   public BigInteger[] signCard(){
 
       if(norequest != null){
       BigInteger[] signedCard = new BigInteger[candidates];
       for (int j = 1; j <= candidates; ++j)
       signedCard[j-1] = codedcards[norequest][j-1].modPow(d,mod);
       return signedCard;
       }
       return null;
   }
 
 /**
 * check if vote after encrypt is formated correctly (if it is it means that vote
 * was decrypted by private key of VotingServer)
 */   
   public boolean checkVote(BigInteger vote){
 
        vote = vote.modPow(e,mod);
        int candidate = Integer.parseInt(Character.toString(vote.toString().charAt(0)));
        //check here if vote is unique (in database)
        if(vote.toString().length()==10 && candidate <= candidates && candidate >= 0){
 
            collectVote(vote);
            return true;
 
        } 
        System.out.println("VOTE INCORRECT!:"+vote.toString());   
        return false;
 
   }
 
 /**
 * add vote to database
 */      
   private void collectVote(BigInteger vote){
 
       //add here function to add vote to database
         System.out.println("VOTE:"+vote+" ADDED TO DATABASE.");   
   }
}

And finally example of local usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package blindsignature;
 
 
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
 
 
/**
 * Blind Signature is a class which presents how to use VotingClient and 
 * VotingServer Class to do full process of voting with blind signature
 * 
 * 
 * @author Pawel Maniora
 * @version 0.2, 20/01/12
 */
 
public class BlindSignature {
 
   /**
   * number of candidates on voting cards
   */
    final static int CANDIDATES = 4;
 
   /**
   * numbers of cards - the higher amount - the safer and
   * slower voting is.
   */    
    final static int CARDAMOUNT = 4;
 
   /**
   * server-side of blind signature voting module. 
   */    
    public static VotingServer vs;
 
   /**
   * client-side of blind signature voting module. 
   */    
    public static VotingClient vc;
 
 
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws NoSuchProviderException, InvalidKeyException, SignatureException {
 
 
        try {
 
        //Create VotingServer and VotingClient
        //VotingServer should be created for each voter - it keeps codedCards,
        // randomly choosen number etc.
        vs = new VotingServer(CANDIDATES,CARDAMOUNT,d,e,mod);
        vc = new VotingClient(CANDIDATES,CARDAMOUNT,e,mod);
 
        //send coded cards from client to server
        vs.setCodedCards(vc.getCodedCards());
 
        //VotingServer draw no request parameter and send info to VotingClient
        vc.setRfinal(vs.drawNoRequest());
 
        //VotingServer gets info about r' parameters and if its okay sand signed card to client
        if(vs.checkCards(vc.getRprim()))
        vc.setSignedCard(vs.signCard());
 
        //after Reconnect in anonymous connection
        // send vote on candidate (2 is third in this example) to serwer. if everything is okay vote is added. 
        vc.isVoteAccepted(vs.checkVote(vc.sendVote(2)));
 
        }catch (java.security.NoSuchAlgorithmException e) {System.out.println("NoSuchAlgorithmException");}
    }
}

You can download sources from here

Have your say