@@ -4,8 +4,11 @@ package blindrsa
4
4
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02
5
5
6
6
import (
7
+ "crypto"
7
8
"crypto/rand"
8
9
"crypto/rsa"
10
+ "crypto/sha256"
11
+ "crypto/sha512"
9
12
"crypto/subtle"
10
13
"errors"
11
14
"hash"
@@ -15,21 +18,63 @@ import (
15
18
"github.com/cloudflare/circl/blindsign"
16
19
)
17
20
21
+ var errUnsupportedHashFunction = errors .New ("unsupported hash function" )
22
+
18
23
// An RSAVerifier represents a Verifier in the RSA blind signature protocol.
19
24
// It carries state needed to produce and validate an RSA blind signature.
20
25
type RSAVerifier struct {
21
26
// Public key of the Signer
22
27
pk * rsa.PublicKey
23
28
29
+ // Identifier of the cryptographic hash function used in producing the message signature
30
+ cryptoHash crypto.Hash
31
+
24
32
// Hash function used in producing the message signature
25
33
hash hash.Hash
26
34
}
27
35
36
+ // A DeterminsiticRSAVerifier is an RSAVerifier that supports deterministic signatures.
37
+ type DeterminsiticRSAVerifier struct {
38
+ // Public key of the Signer
39
+ pk * rsa.PublicKey
40
+
41
+ // Identifier of the cryptographic hash function used in producing the message signature
42
+ cryptoHash crypto.Hash
43
+
44
+ // Hash function used in producing the message signature
45
+ hash hash.Hash
46
+ }
47
+
48
+ func convertHashFunction (hash crypto.Hash ) hash.Hash {
49
+ switch hash {
50
+ case crypto .SHA256 :
51
+ return sha256 .New ()
52
+ case crypto .SHA384 :
53
+ return sha512 .New384 ()
54
+ case crypto .SHA512 :
55
+ return sha512 .New ()
56
+ default :
57
+ panic (errUnsupportedHashFunction )
58
+ }
59
+ }
60
+
61
+ // NewDeterministicRSAVerifier creates a new RSAVerifier using the corresponding Signer parameters.
62
+ func NewDeterministicRSAVerifier (pk * rsa.PublicKey , hash crypto.Hash ) DeterminsiticRSAVerifier {
63
+ h := convertHashFunction (hash )
64
+ return DeterminsiticRSAVerifier {
65
+ pk : pk ,
66
+ cryptoHash : hash ,
67
+ hash : h ,
68
+ }
69
+ }
70
+
28
71
// NewRSAVerifier creates a new RSAVerifier using the corresponding Signer parameters.
29
- func NewRSAVerifier (pk * rsa.PublicKey , hash hash.Hash ) RSAVerifier {
72
+ func NewRSAVerifier (pk * rsa.PublicKey , hash crypto.Hash ) RSAVerifier {
73
+ h := convertHashFunction (hash )
30
74
return RSAVerifier {
31
- pk : pk ,
32
- hash : hash ,
75
+ pk : pk ,
76
+ cryptoHash : hash ,
77
+ hash : h ,
33
78
}
34
79
}
35
80
@@ -64,32 +109,68 @@ func generateBlindingFactor(random io.Reader, key *rsa.PublicKey) (*big.Int, *bi
64
109
return r , rInv , nil
65
110
}
66
111
67
- func ( v RSAVerifier ) fixedBlind (message , salt []byte , r , rInv * big.Int ) ([]byte , blindsign.VerifierState , error ) {
68
- encodedMsg , err := encodeMessageEMSAPSS (message , v . pk , v . hash , salt )
112
+ func fixedBlind (message , salt []byte , r , rInv * big.Int , pk * rsa. PublicKey , hash hash. Hash ) ([]byte , blindsign.VerifierState , error ) {
113
+ encodedMsg , err := encodeMessageEMSAPSS (message , pk , hash , salt )
69
114
if err != nil {
70
115
return nil , nil , err
71
116
}
72
117
73
118
m := new (big.Int ).SetBytes (encodedMsg )
74
119
75
- bigE := big .NewInt (int64 (v . pk .E ))
76
- x := new (big.Int ).Exp (r , bigE , v . pk .N )
120
+ bigE := big .NewInt (int64 (pk .E ))
121
+ x := new (big.Int ).Exp (r , bigE , pk .N )
77
122
z := new (big.Int ).Set (m )
78
123
z .Mul (z , x )
79
- z .Mod (z , v . pk .N )
124
+ z .Mod (z , pk .N )
80
125
81
- kLen := (v . pk .N .BitLen () + 7 ) / 8
126
+ kLen := (pk .N .BitLen () + 7 ) / 8
82
127
blindedMsg := make ([]byte , kLen )
83
128
z .FillBytes (blindedMsg )
84
129
85
130
return blindedMsg , RSAVerifierState {
86
131
encodedMsg : encodedMsg ,
87
- verifier : v ,
132
+ pk : pk ,
133
+ hash : hash ,
88
134
salt : salt ,
89
135
rInv : rInv ,
90
136
}, nil
91
137
}
92
138
139
+ // Blind initializes the blind RSA protocol using an input message and source of randomness. The
140
+ // signature is deterministic. This function fails if randomness was not provided.
141
+ //
142
+ // See the specification for more details:
143
+ // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.1
144
+ func (v DeterminsiticRSAVerifier ) Blind (random io.Reader , message []byte ) ([]byte , blindsign.VerifierState , error ) {
145
+ if random == nil {
146
+ return nil , nil , ErrInvalidRandomness
147
+ }
148
+
149
+ r , rInv , err := generateBlindingFactor (random , v .pk )
150
+ if err != nil {
151
+ return nil , nil , err
152
+ }
153
+
154
+ return fixedBlind (message , nil , r , rInv , v .pk , v .hash )
155
+ }
156
+
157
+ func verifyMessageSignature (message , signature []byte , saltLength int , pk * rsa.PublicKey , hash crypto.Hash ) error {
158
+ h := convertHashFunction (hash )
159
+ h .Write (message )
160
+ digest := h .Sum (nil )
161
+
162
+ err := rsa .VerifyPSS (pk , hash , digest , signature , & rsa.PSSOptions {
163
+ Hash : hash ,
164
+ SaltLength : saltLength ,
165
+ })
166
+ return err
167
+ }
168
+
169
+ // Verify verifies the input (message, signature) pair and produces an error upon failure.
170
+ func (v DeterminsiticRSAVerifier ) Verify (message , signature []byte ) error {
171
+ return verifyMessageSignature (message , signature , 0 , v .pk , v .cryptoHash )
172
+ }
173
+
93
174
// Blind initializes the blind RSA protocol using an input message and source of randomness. The
94
175
// signature includes a randomly generated PSS salt whose length equals the size of the underlying
95
176
// hash function. This function fails if randomness was not provided.
@@ -112,7 +193,7 @@ func (v RSAVerifier) Blind(random io.Reader, message []byte) ([]byte, blindsign.
112
193
return nil , nil , err
113
194
}
114
195
115
- return v . fixedBlind (message , salt , r , rInv )
196
+ return fixedBlind (message , salt , r , rInv , v . pk , v . hash )
116
197
}
117
198
118
199
// FixedBlind runs the Blind function with fixed blind and salt inputs.
@@ -127,14 +208,22 @@ func (v RSAVerifier) FixedBlind(message, blind, salt []byte) ([]byte, blindsign.
127
208
return nil , nil , ErrInvalidBlind
128
209
}
129
210
130
- return v .fixedBlind (message , salt , r , rInv )
211
+ return fixedBlind (message , salt , r , rInv , v .pk , v .hash )
212
+ }
213
+
214
+ // Verify verifies the input (message, signature) pair and produces an error upon failure.
215
+ func (v RSAVerifier ) Verify (message , signature []byte ) error {
216
+ return verifyMessageSignature (message , signature , v .hash .Size (), v .pk , v .cryptoHash )
131
217
}
132
218
133
219
// An RSAVerifierState carries state needed to complete the blind signature protocol
134
220
// as a verifier.
135
221
type RSAVerifierState struct {
136
- // An RSA verifier carrying Signer verification state
137
- verifier RSAVerifier
222
+ // Public key of the Signer
223
+ pk * rsa.PublicKey
224
+
225
+ // Hash function used in producing the message signature
226
+ hash hash.Hash
138
227
139
228
// The hashed and encoded message being signed
140
229
encodedMsg []byte
@@ -163,20 +252,20 @@ func verifyBlindSignature(pub *rsa.PublicKey, hashed, sig []byte) error {
163
252
// See the specification for more details:
164
253
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-rsa-blind-signatures-02#section-5.1.3
165
254
func (state RSAVerifierState ) Finalize (data []byte ) ([]byte , error ) {
166
- kLen := (state .verifier . pk .N .BitLen () + 7 ) / 8
255
+ kLen := (state .pk .N .BitLen () + 7 ) / 8
167
256
if len (data ) != kLen {
168
257
return nil , ErrUnexpectedSize
169
258
}
170
259
171
260
z := new (big.Int ).SetBytes (data )
172
261
s := new (big.Int ).Set (state .rInv )
173
262
s .Mul (s , z )
174
- s .Mod (s , state .verifier . pk .N )
263
+ s .Mod (s , state .pk .N )
175
264
176
265
sig := make ([]byte , kLen )
177
266
s .FillBytes (sig )
178
267
179
- err := verifyBlindSignature (state .verifier . pk , state .encodedMsg , sig )
268
+ err := verifyBlindSignature (state .pk , state .encodedMsg , sig )
180
269
if err != nil {
181
270
return nil , err
182
271
}
@@ -186,7 +275,7 @@ func (state RSAVerifierState) Finalize(data []byte) ([]byte, error) {
186
275
187
276
// CopyBlind returns an encoding of the blind value used in the protocol.
188
277
func (state RSAVerifierState ) CopyBlind () []byte {
189
- r := new (big.Int ).ModInverse (state .rInv , state .verifier . pk .N )
278
+ r := new (big.Int ).ModInverse (state .rInv , state .pk .N )
190
279
return r .Bytes ()
191
280
}
192
281
0 commit comments