1 package blindrsa
2
3 import (
4 "bytes"
5 "crypto"
6 "crypto/rand"
7 "crypto/rsa"
8 "crypto/x509"
9 "encoding/hex"
10 "encoding/json"
11 "encoding/pem"
12 "fmt"
13 "io"
14 "math/big"
15 "os"
16 "strings"
17 "testing"
18
19 "github.com/cloudflare/circl/internal/test"
20 )
21
22
23 const testPrivateKey = `
24 -----BEGIN RSA PRIVATE KEY-----
25 MIIEowIBAAKCAQEAyxrta2qV9bHOATpM/KsluUsuZKIwNOQlCn6rQ8DfOowSmTrx
26 KxEZCNS0cb7DHUtsmtnN2pBhKi7pA1I+beWiJNawLwnlw3TQz+Adj1KcUAp4ovZ5
27 CPpoK1orQwyB6vGvcte155T8mKMTknaHl1fORTtSbvm/bOuZl5uEI7kPRGGiKvN6
28 qwz1cz91l6vkTTHHMttooYHGy75gfYwOUuBlX9mZbcWE7KC+h6+814ozfRex26no
29 KLvYHikTFxROf/ifVWGXCbCWy7nqR0zq0mTCBz/kl0DAHwDhCRBgZpg9IeX4Pwhu
30 LoI8h5zUPO9wDSo1Kpur1hLQPK0C2xNLfiJaXwIDAQABAoIBAC8wm3c4tYz3efDJ
31 Ffgi38n0kNvq3x5636xXj/1XA8a7otqdWklyWIm3uhEvjG/zBVHZRz4AC8NcUOFn
32 q3+nOgwrIZZcS1klfBrAbL3PKOhj9nGOqMKQQ8HG2oRilJD9BJG/UtFyyVnBkhuW
33 lJxyV0e4p8eHGZX6C56xEHuoVMbDKm9HR8XRwwTHRn1VsICqIzo6Uv/fJhFMu1Qf
34 +mtpa3oJb43P9pygirWO+w+3U6pRhccwAWlrvOjAmeP0Ndy7/gXn26rSPbKmWcI6
35 3VIUB/FQsa8tkFTEFkIp1oQLejKk+EgUk66JWc8K6o3vDDyfdbmjTHVxi3ByyNur
36 F87+ykkCgYEA73MLD1FLwPWdmV/V+ZiMTEwTXRBc1W1D7iigNclp9VDAzXFI6ofs
37 3v+5N8hcZIdEBd9W6utHi/dBiEogDuSjljPRCqPsQENm2itTHzmNRvvI8wV1KQbP
38 eJOd0vPMl5iup8nYL+9ASfGYeX5FKlttKEm4ZIY0XUsx9pERoq4PlEsCgYEA2STJ
39 68thMWv9xKuz26LMQDzImJ5OSQD0hsts9Ge01G/rh0Dv/sTzO5wtLsiyDA/ZWkzB
40 8J+rO/y2xqBD9VkYKaGB/wdeJP0Z+n7sETetiKPbXPfgAi7VAe77Rmst/oEcGLUg
41 tm+XnfJSInoLU5HmtIdLg0kcQLVbN5+ZMmtkPb0CgYBSbhczmbfrYGJ1p0FBIFvD
42 9DiCRBzBOFE3TnMAsSqx0a/dyY7hdhN8HSqE4ouz68DmCKGiU4aYz3CW23W3ysvp
43 7EKdWBr/cHSazGlcCXLyKcFer9VKX1bS2nZtZZJb6arOhjTPI5zNF8d2o5pp33lv
44 chlxOaYTK8yyZfRdPXCNiwKBgQDV77oFV66dm7E9aJHerkmgbIKSYz3sDUXd3GSv
45 c9Gkj9Q0wNTzZKXkMB4P/un0mlTh88gMQ7PYeUa28UWjX7E/qwFB+8dUmA1VUGFT
46 IVEW06GXuhv46p0wt3zXx1dcbWX6LdJaDB4MHqevkiDAqHntmXLbmVd9pXCGn/a2
47 xznO3QKBgHkPJPEiCzRugzgN9UxOT5tNQCSGMOwJUd7qP0TWgvsWHT1N07JLgC8c
48 Yg0f1rCxEAQo5BVppiQFp0FA7W52DUnMEfBtiehZ6xArW7crO91gFRqKBWZ3Jjyz
49 /JcS8m5UgQxC8mmb/2wLD5TDvWw+XCfjUgWmvqIi5dcJgmuTAn5X
50 -----END RSA PRIVATE KEY-----`
51
52 func loadPrivateKey() (*rsa.PrivateKey, error) {
53 block, _ := pem.Decode([]byte(testPrivateKey))
54 if block == nil || block.Type != "RSA PRIVATE KEY" {
55 return nil, fmt.Errorf("PEM private key decoding failed")
56 }
57
58 privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
59 if err != nil {
60 return nil, err
61 }
62
63 return privateKey, nil
64 }
65
66 func mustDecodeHex(h string) []byte {
67 b, err := hex.DecodeString(h)
68 if err != nil {
69 panic(err)
70 }
71 return b
72 }
73
74 func loadStrongRSAKey() *rsa.PrivateKey {
75
76 pEnc := "dcd90af1be463632c0d5ea555256a20605af3db667475e190e3af12a34a3324c46a3094062c59fb4b249e0ee6afba8bee14e0276d126c99f4784b23009bf6168ff628ac1486e5ae8e23ce4d362889de4df63109cbd90ef93db5ae64372bfe1c55f832766f21e94ea3322eb2182f10a891546536ba907ad74b8d72469bea396f3"
77 qEnc := "f8ba5c89bd068f57234a3cf54a1c89d5b4cd0194f2633ca7c60b91a795a56fa8c8686c0e37b1c4498b851e3420d08bea29f71d195cfbd3671c6ddc49cf4c1db5b478231ea9d91377ffa98fe95685fca20ba4623212b2f2def4da5b281ed0100b651f6db32112e4017d831c0da668768afa7141d45bbc279f1e0f8735d74395b3"
78 NEnc := "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552e2318d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c17d4382a0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121e73976e4facba9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe03106c12acb1e7bb53d75ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318081fa7e1b65a37774e8e50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e722258ab705c76d43e5f1f121b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70a7153213c39ae371b2b5dc1dafcb19d6fae9"
79 eEnc := "010001"
80 dEnc := "4e21356983722aa1adedb084a483401c1127b781aac89eab103e1cfc52215494981d18dd8028566d9d499469c25476358de23821c78a6ae43005e26b394e3051b5ca206aa9968d68cae23b5affd9cbb4cb16d64ac7754b3cdba241b72ad6ddfc000facdb0f0dd03abd4efcfee1730748fcc47b7621182ef8af2eeb7c985349f62ce96ab373d2689baeaea0e28ea7d45f2d605451920ca4ea1f0c08b0f1f6711eaa4b7cca66d58a6b916f9985480f90aca97210685ac7b12d2ec3e30a1c7b97b65a18d38a93189258aa346bf2bc572cd7e7359605c20221b8909d599ed9d38164c9c4abf396f897b9993c1e805e574d704649985b600fa0ced8e5427071d7049d"
81
82 p := new(big.Int).SetBytes(mustDecodeHex(pEnc))
83 q := new(big.Int).SetBytes(mustDecodeHex(qEnc))
84 N := new(big.Int).SetBytes(mustDecodeHex(NEnc))
85 e := new(big.Int).SetBytes(mustDecodeHex(eEnc))
86 d := new(big.Int).SetBytes(mustDecodeHex(dEnc))
87
88 primes := make([]*big.Int, 2)
89 primes[0] = p
90 primes[1] = q
91
92 key := &rsa.PrivateKey{
93 PublicKey: rsa.PublicKey{
94 N: N,
95 E: int(e.Int64()),
96 },
97 D: d,
98 Primes: primes,
99 }
100
101 return key
102 }
103
104 func runSignatureProtocol(signer Signer, verifier Verifier, message []byte, random io.Reader) ([]byte, error) {
105 blindedMsg, state, err := verifier.Blind(random, message)
106 if err != nil {
107 return nil, err
108 }
109
110 kLen := (signer.sk.N.BitLen() + 7) / 8
111 if len(blindedMsg) != kLen {
112 return nil, fmt.Errorf("Protocol message (blind message) length mismatch, expected %d, got %d", kLen, len(blindedMsg))
113 }
114
115 blindedSig, err := signer.BlindSign(blindedMsg)
116 if err != nil {
117 return nil, err
118 }
119
120 if len(blindedSig) != kLen {
121 return nil, fmt.Errorf("Protocol message (blind signature) length mismatch, expected %d, got %d", kLen, len(blindedMsg))
122 }
123
124 sig, err := state.Finalize(blindedSig)
125 if err != nil {
126 return nil, err
127 }
128
129 err = verifier.Verify(message, sig)
130 if err != nil {
131 return nil, err
132 }
133
134 return sig, nil
135 }
136
137 func TestRoundTrip(t *testing.T) {
138 message := []byte("hello world")
139 key, err := loadPrivateKey()
140 if err != nil {
141 t.Fatal(err)
142 }
143
144 verifier := NewVerifier(&key.PublicKey, crypto.SHA512)
145 signer := NewSigner(key)
146
147 sig, err := runSignatureProtocol(signer, verifier, message, rand.Reader)
148 if err != nil {
149 t.Fatal(err)
150 }
151 if sig == nil {
152 t.Fatal("nil signature output")
153 }
154 }
155
156 func TestDeterministicRoundTrip(t *testing.T) {
157 message := []byte("hello world")
158 key, err := loadPrivateKey()
159 if err != nil {
160 t.Fatal(err)
161 }
162
163 verifier := NewDeterministicVerifier(&key.PublicKey, crypto.SHA512)
164 signer := NewSigner(key)
165
166 sig, err := runSignatureProtocol(signer, verifier, message, rand.Reader)
167 if err != nil {
168 t.Fatal(err)
169 }
170 if sig == nil {
171 t.Fatal("nil signature output")
172 }
173 }
174
175 func TestDeterministicBlindFailure(t *testing.T) {
176 message := []byte("hello world")
177 key, err := loadPrivateKey()
178 if err != nil {
179 t.Fatal(err)
180 }
181
182 verifier := NewDeterministicVerifier(&key.PublicKey, crypto.SHA512)
183 signer := NewSigner(key)
184
185 _, err = runSignatureProtocol(signer, verifier, message, nil)
186 if err == nil {
187 t.Fatal("Expected signature generation to fail with empty randomness")
188 }
189 }
190
191 func TestRandomSignVerify(t *testing.T) {
192 message := []byte("hello world")
193 key, err := loadPrivateKey()
194 if err != nil {
195 t.Fatal(err)
196 }
197
198 verifier := NewVerifier(&key.PublicKey, crypto.SHA512)
199 signer := NewSigner(key)
200
201 sig1, err := runSignatureProtocol(signer, verifier, message, rand.Reader)
202 if err != nil {
203 t.Fatal(err)
204 }
205 sig2, err := runSignatureProtocol(signer, verifier, message, rand.Reader)
206 if err != nil {
207 t.Fatal(err)
208 }
209
210 if sig1 == nil || sig2 == nil {
211 t.Fatal("nil signature output")
212 }
213 if bytes.Equal(sig1, sig2) {
214 t.Fatal("random signatures matched when they should differ")
215 }
216 }
217
218 type mockRandom struct {
219 counter uint8
220 }
221
222 func (r *mockRandom) Read(p []byte) (n int, err error) {
223 for i := range p {
224 p[i] = r.counter
225 r.counter = r.counter + 1
226 }
227 return len(p), nil
228 }
229
230 func TestFixedRandomSignVerify(t *testing.T) {
231 message := []byte("hello world")
232 key, err := loadPrivateKey()
233 if err != nil {
234 t.Fatal(err)
235 }
236
237 verifier := NewVerifier(&key.PublicKey, crypto.SHA512)
238 signer := NewSigner(key)
239
240 mockRand := &mockRandom{0}
241 sig1, err := runSignatureProtocol(signer, verifier, message, mockRand)
242 if err != nil {
243 t.Fatal(err)
244 }
245 mockRand = &mockRandom{0}
246 sig2, err := runSignatureProtocol(signer, verifier, message, mockRand)
247 if err != nil {
248 t.Fatal(err)
249 }
250
251 if sig1 == nil || sig2 == nil {
252 t.Fatal("nil signature output")
253 }
254 if !bytes.Equal(sig1, sig2) {
255 t.Fatal("random signatures with fixed random seeds differ when they should be equal")
256 }
257 }
258
259 type rawTestVector struct {
260 Name string `json:"name"`
261 P string `json:"p"`
262 Q string `json:"q"`
263 N string `json:"n"`
264 E string `json:"e"`
265 D string `json:"d"`
266 Msg string `json:"msg"`
267 MsgPrefix string `json:"msg_prefix"`
268 InputMsg string `json:"input_msg"`
269 Salt string `json:"salt"`
270 SaltLen string `json:"sLen"`
271 IsRandomized string `json:"is_randomized"`
272 Inv string `json:"inv"`
273 BlindedMessage string `json:"blinded_msg"`
274 BlindSig string `json:"blind_sig"`
275 Sig string `json:"sig"`
276 }
277
278 type testVector struct {
279 t *testing.T
280 name string
281 p *big.Int
282 q *big.Int
283 n *big.Int
284 e int
285 d *big.Int
286 msg []byte
287 msgPrefix []byte
288 inputMsg []byte
289 salt []byte
290 saltLen int
291 isRandomized bool
292 blindInverse *big.Int
293 blindedMessage []byte
294 blindSig []byte
295 sig []byte
296 }
297
298 type testVectorList struct {
299 t *testing.T
300 vectors []testVector
301 }
302
303 func mustUnhexBigInt(number string) *big.Int {
304 data := mustUnhex(number)
305 value := new(big.Int)
306 value.SetBytes(data)
307 return value
308 }
309
310 func mustUnhex(value string) []byte {
311 value = strings.TrimPrefix(value, "0x")
312 data, err := hex.DecodeString(value)
313 if err != nil {
314 panic(err)
315 }
316
317 return data
318 }
319
320 func mustUnhexInt(value string) int {
321 number := mustUnhexBigInt(value)
322 result := int(number.Int64())
323 return result
324 }
325
326 func (tv *testVector) UnmarshalJSON(data []byte) error {
327 raw := rawTestVector{}
328 err := json.Unmarshal(data, &raw)
329 if err != nil {
330 return err
331 }
332
333 tv.name = raw.Name
334 tv.p = mustUnhexBigInt(raw.P)
335 tv.q = mustUnhexBigInt(raw.Q)
336 tv.n = mustUnhexBigInt(raw.N)
337 tv.e = mustUnhexInt(raw.E)
338 tv.d = mustUnhexBigInt(raw.D)
339 tv.msg = mustUnhex(raw.Msg)
340 tv.msgPrefix = mustUnhex(raw.MsgPrefix)
341 tv.inputMsg = mustUnhex(raw.InputMsg)
342 tv.salt = mustUnhex(raw.Salt)
343 tv.saltLen = mustUnhexInt(raw.SaltLen)
344 tv.isRandomized = mustUnhexInt(raw.IsRandomized) != 0
345 tv.blindedMessage = mustUnhex(raw.BlindedMessage)
346 tv.blindInverse = mustUnhexBigInt(raw.Inv)
347 tv.blindSig = mustUnhex(raw.BlindSig)
348 tv.sig = mustUnhex(raw.Sig)
349
350 return nil
351 }
352
353 func (tvl testVectorList) MarshalJSON() ([]byte, error) {
354 return json.Marshal(tvl.vectors)
355 }
356
357 func (tvl *testVectorList) UnmarshalJSON(data []byte) error {
358 err := json.Unmarshal(data, &tvl.vectors)
359 if err != nil {
360 return err
361 }
362
363 for i := range tvl.vectors {
364 tvl.vectors[i].t = tvl.t
365 }
366
367 return nil
368 }
369
370 func verifyTestVector(t *testing.T, vector testVector) {
371 key := new(rsa.PrivateKey)
372 key.PublicKey.N = vector.n
373 key.PublicKey.E = vector.e
374 key.D = vector.d
375 key.Primes = []*big.Int{vector.p, vector.q}
376 key.Precomputed.Dp = nil
377
378
379 rInv := new(big.Int).Set(vector.blindInverse)
380 r := new(big.Int).ModInverse(rInv, key.N)
381 if r == nil {
382 t.Fatal("Failed to compute blind inverse")
383 }
384
385 signer := NewSigner(key)
386
387 var verifier Verifier
388 switch vector.name {
389 case "RSABSSA-SHA384-PSS-Deterministic":
390 verifier = NewVerifier(&key.PublicKey, crypto.SHA384)
391 case "RSABSSA-SHA384-PSSZERO-Deterministic":
392 verifier = NewDeterministicVerifier(&key.PublicKey, crypto.SHA384)
393 case "RSABSSA-SHA384-PSS-Randomized", "RSABSSA-SHA384-PSSZERO-Randomized":
394 t.Skipf("variant %v not supported yet", vector.name)
395 default:
396 t.Fatal("variant not supported")
397 }
398
399 inputMsg := prepareMsg(vector.msg, vector.msgPrefix)
400 got := hex.EncodeToString(inputMsg)
401 want := hex.EncodeToString(vector.inputMsg)
402 if got != want {
403 test.ReportError(t, got, want)
404 }
405
406 blindedMsg, state, err := fixedBlind(inputMsg, vector.salt, r, rInv, &key.PublicKey, verifier.Hash())
407 test.CheckNoErr(t, err, "fixedBlind failed")
408 got = hex.EncodeToString(blindedMsg)
409 want = hex.EncodeToString(vector.blindedMessage)
410 if got != want {
411 test.ReportError(t, got, want)
412 }
413
414 blindSig, err := signer.BlindSign(blindedMsg)
415 test.CheckNoErr(t, err, "blindSign failed")
416 got = hex.EncodeToString(blindSig)
417 want = hex.EncodeToString(vector.blindSig)
418 if got != want {
419 test.ReportError(t, got, want)
420 }
421
422 sig, err := state.Finalize(blindSig)
423 test.CheckNoErr(t, err, "finalize failed")
424 got = hex.EncodeToString(sig)
425 want = hex.EncodeToString(vector.sig)
426 if got != want {
427 test.ReportError(t, got, want)
428 }
429
430 err = verifier.Verify(inputMsg, sig)
431 test.CheckNoErr(t, err, "verification failed")
432 }
433
434 func TestVectors(t *testing.T) {
435 data, err := os.ReadFile("testdata/test_vectors_rfc9474.json")
436 if err != nil {
437 t.Fatal("Failed reading test vectors:", err)
438 }
439
440 tvl := &testVectorList{}
441 err = tvl.UnmarshalJSON(data)
442 if err != nil {
443 t.Fatal("Failed deserializing test vectors:", err)
444 }
445
446 for _, vector := range tvl.vectors {
447 t.Run(vector.name, func(tt *testing.T) {
448 verifyTestVector(tt, vector)
449 })
450 }
451 }
452
453 func BenchmarkBRSA(b *testing.B) {
454 message := []byte("hello world")
455 key := loadStrongRSAKey()
456
457 verifier := NewVerifier(&key.PublicKey, crypto.SHA512)
458 signer := NewSigner(key)
459
460 var err error
461 var blindedMsg []byte
462 var state VerifierState
463 b.Run("Blind", func(b *testing.B) {
464 for n := 0; n < b.N; n++ {
465 blindedMsg, state, err = verifier.Blind(rand.Reader, message)
466 if err != nil {
467 b.Fatal(err)
468 }
469 }
470 })
471
472 var blindedSig []byte
473 b.Run("BlindSign", func(b *testing.B) {
474 for n := 0; n < b.N; n++ {
475 blindedSig, err = signer.BlindSign(blindedMsg)
476 if err != nil {
477 b.Fatal(err)
478 }
479 }
480 })
481
482 var sig []byte
483 b.Run("Finalize", func(b *testing.B) {
484 for n := 0; n < b.N; n++ {
485 sig, err = state.Finalize(blindedSig)
486 if err != nil {
487 b.Fatal(err)
488 }
489 }
490 })
491
492 err = verifier.Verify(message, sig)
493 if err != nil {
494 b.Fatal(err)
495 }
496 }
497
498 func Example_blindrsa() {
499
500
501
502 sk, err := rsa.GenerateKey(rand.Reader, 2048)
503 if err != nil {
504 fmt.Fprintf(os.Stderr, "failed to generate RSA key: %v", err)
505 return
506 }
507 pk := &sk.PublicKey
508 server := NewSigner(sk)
509
510
511 verifier := NewVerifier(pk, crypto.SHA384)
512
513
514
515
516 msg := []byte("alice and bob")
517 blindedMsg, state, err := verifier.Blind(rand.Reader, msg)
518 if err != nil {
519 fmt.Fprintf(os.Stderr, "client failed to generate blinded message: %v", err)
520 return
521 }
522
523
524 blindedSignature, err := server.BlindSign(blindedMsg)
525 if err != nil {
526 fmt.Fprintf(os.Stderr, "server failed to sign: %v", err)
527 return
528 }
529
530
531 signature, err := state.Finalize(blindedSignature)
532 if err != nil {
533 fmt.Fprintf(os.Stderr, "client failed to obtain signature: %v", err)
534 return
535 }
536
537
538 ok := verifier.Verify(msg, signature)
539 fmt.Printf("Valid signature: %v", ok == nil)
540
541 }
542
View as plain text