-
Notifications
You must be signed in to change notification settings - Fork 13
/
rsablind2.js
137 lines (120 loc) · 4.3 KB
/
rsablind2.js
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
const secureRandom = require('secure-random');
const BigInteger = require('jsbn').BigInteger;
const sha256 = require('js-sha256');
const NodeRSA = require('node-rsa');
function keyGeneration(params) {
const key = new NodeRSA(params || { b: 2048 });
return key;
}
function keyProperties(key) {
const bigE = new BigInteger(key.keyPair.e.toString());
const bigN = key.keyPair.n;
const bigD = key.keyPair.d;
const bigP = key.keyPair.p;
const bigQ = key.keyPair.q;
return {
bigE,
bigN,
bigD,
bigP,
bigQ,
};
}
function messageToHash(message) {
const messageHash = sha256(message);
return messageHash;
}
function messageToHashInt(message) {
const messageHash = messageToHash(message);
const messageBig = new BigInteger(messageHash, 16);
return messageBig;
}
function blind({ message, key, N, E }) {
const messageHash = messageToHashInt(message);
const bigN = key ? key.keyPair.n : new BigInteger(N.toString());
const bigE = key
? new BigInteger(key.keyPair.e.toString())
: new BigInteger(E.toString());
const bigOne = new BigInteger('1');
let gcd;
let r;
do {
r = new BigInteger(secureRandom(64));
gcd = r.gcd(bigN);
// console.log('Try');
} while (
!gcd.equals(bigOne) ||
r.compareTo(bigN) >= 0 ||
r.compareTo(bigOne) <= 0
);
// now that we got an r that satisfies the restrictions described we can proceed with calculation of mu
const mu = r.modPow(bigE, bigN).multiply(messageHash).mod(bigN); // Alice computes mu = H(msg) * r^e mod N
return {
blinded: mu,
r,
};
}
function sign({ blinded, key }) {
const { bigN, bigP, bigQ, bigD } = keyProperties(key);
const mu = new BigInteger(blinded.toString());
// We split the mu^d modN in two , one mode p , one mode q
const PinverseModQ = bigP.modInverse(bigQ); // calculate p inverse modulo q
const QinverseModP = bigQ.modInverse(bigP); // calculate q inverse modulo p
// We split the message mu in to messages m1, m2 one mod p, one mod q
const m1 = mu.modPow(bigD, bigN).mod(bigP); // calculate m1=(mu^d modN)modP
const m2 = mu.modPow(bigD, bigN).mod(bigQ); // calculate m2=(mu^d modN)modQ
// We combine the calculated m1 and m2 in order to calculate muprime
// We calculate muprime: (m1*Q*QinverseModP + m2*P*PinverseModQ) mod N where N =P*Q
const muprime = m1
.multiply(bigQ)
.multiply(QinverseModP)
.add(m2.multiply(bigP).multiply(PinverseModQ))
.mod(bigN);
return muprime;
}
function unblind({ signed, key, r, N }) {
const bigN = key ? key.keyPair.n : new BigInteger(N.toString());
const muprime = new BigInteger(signed.toString());
const s = r.modInverse(bigN).multiply(muprime).mod(bigN); // Alice computes sig = mu'*r^-1 mod N, inverse of r mod N multiplied with muprime mod N, to remove the blinding factor
return s;
}
function verify({ unblinded, key, message, E, N }) {
const signature = new BigInteger(unblinded.toString());
const messageHash = messageToHashInt(message);
const bigN = key ? key.keyPair.n : new BigInteger(N.toString());
const bigE = key
? new BigInteger(key.keyPair.e.toString())
: new BigInteger(E.toString());
const signedMessageBigInt = signature.modPow(bigE, bigN); // calculate sig^e modN, if we get back the initial message that means that the signature is valid, this works because (m^d)^e modN = m
const result = messageHash.equals(signedMessageBigInt);
return result;
}
function verify2({ unblinded, key, message }) {
const signature = new BigInteger(unblinded.toString());
const messageHash = messageToHashInt(message);
const { bigD, bigN } = keyProperties(key);
const msgSig = messageHash.modPow(bigD, bigN); // calculate H(msg)^d modN, if we get back the signature that means the message was signed
const result = signature.equals(msgSig);
return result;
}
function verifyBlinding({ blinded, r, unblinded, key, E, N }) {
const messageHash = messageToHashInt(unblinded);
r = new BigInteger(r.toString());
N = key ? key.keyPair.n : new BigInteger(N.toString());
E = key
? new BigInteger(key.keyPair.e.toString())
: new BigInteger(E.toString());
const blindedHere = messageHash.multiply(r.modPow(E, N)).mod(N);
const result = blindedHere.equals(blinded);
return result;
}
module.exports = {
keyGeneration,
messageToHash,
blind,
sign,
unblind,
verify,
verify2,
verifyBlinding,
};