1
+ var bn = require ( 'bn.js' ) ;
2
+ module . exports = crt ;
3
+ // based on https://github.com/google/end-to-end/blob/bd14d9607e742cd94b1a5af39e0f9e8c454b4a32/src/javascript/crypto/e2e/asymmetric/rsa.js#L196
4
+ function blind ( priv , crypto ) {
5
+ var mod = bn . mont ( priv . modulus ) ;
6
+ var r = getr ( priv , crypto ) ;
7
+ var p = priv . prime1 ;
8
+ var q = priv . prime2 ;
9
+ var ONE = new bn ( 1 ) ;
10
+
11
+ var blinder = r . toRed ( mod )
12
+ . redPow ( new bn ( priv . publicExponent ) ) . fromRed ( ) ;
13
+ return {
14
+ blinder : blinder ,
15
+ unblinder :r . invm ( priv . modulus )
16
+ } ;
17
+ }
18
+ function crt ( msg , priv , crypto ) {
19
+ var blinds = blind ( priv , crypto ) ;
20
+ var mod = bn . mont ( priv . modulus ) ;
21
+ var blinded = new bn ( msg ) . mul ( blinds . blinder ) . mod ( priv . modulus ) ;
22
+ var c1 = blinded . toRed ( bn . mont ( priv . prime1 ) ) ;
23
+ var c2 = blinded . toRed ( bn . mont ( priv . prime2 ) ) ;
24
+ var qinv = priv . coefficient ;
25
+ var p = priv . prime1 ;
26
+ var q = priv . prime2 ;
27
+ var m1 = c1 . redPow ( priv . exponent1 ) ;
28
+ var m2 = c2 . redPow ( priv . exponent2 ) ;
29
+ m1 = m1 . fromRed ( ) ;
30
+ m2 = m2 . fromRed ( ) ;
31
+ var h = m1 . isub ( m2 ) . imul ( qinv ) . mod ( p ) ;
32
+ h . imul ( q ) ;
33
+ m2 . iadd ( h ) ;
34
+ return new Buffer ( m2 . imul ( blinds . unblinder ) . mod ( priv . modulus ) . toArray ( ) ) ;
35
+ }
36
+
37
+ function getr ( priv , crypto ) {
38
+ var len = priv . modulus . byteLength ( ) ;
39
+ var r = new bn ( crypto . randomBytes ( len ) ) ;
40
+ while ( r . cmp ( priv . modulus ) >= 0 || ! r . mod ( priv . prime1 ) || ! r . mod ( priv . prime2 ) ) {
41
+ r = new bn ( crypto . randomBytes ( len ) ) ;
42
+ }
43
+ return r ;
44
+ }
0 commit comments