@@ -13,7 +13,10 @@ import (
1313 "io"
1414 "math/big"
1515 "os"
16+ "strings"
1617 "testing"
18+
19+ "github.com/cloudflare/circl/internal/test"
1720)
1821
1922// 2048-bit RSA private key
@@ -254,31 +257,39 @@ func TestFixedRandomSignVerify(t *testing.T) {
254257}
255258
256259type rawTestVector struct {
260+ Name string `json:"name"`
257261 P string `json:"p"`
258262 Q string `json:"q"`
259263 N string `json:"n"`
260264 E string `json:"e"`
261265 D string `json:"d"`
262266 Msg string `json:"msg"`
267+ MsgPrefix string `json:"msg_prefix"`
268+ InputMsg string `json:"input_msg"`
263269 Salt string `json:"salt"`
270+ SaltLen string `json:"sLen"`
271+ IsRandomized string `json:"is_randomized"`
264272 Inv string `json:"inv"`
265- EncodedMsg string `json:"encoded_msg"`
266- BlindedMessage string `json:"blinded_message"`
273+ BlindedMessage string `json:"blinded_msg"`
267274 BlindSig string `json:"blind_sig"`
268275 Sig string `json:"sig"`
269276}
270277
271278type testVector struct {
272279 t * testing.T
280+ name string
273281 p * big.Int
274282 q * big.Int
275283 n * big.Int
276284 e int
277285 d * big.Int
278286 msg []byte
287+ msgPrefix []byte
288+ inputMsg []byte
279289 salt []byte
290+ saltLen int
291+ isRandomized bool
280292 blindInverse * big.Int
281- encodedMessage []byte
282293 blindedMessage []byte
283294 blindSig []byte
284295 sig []byte
@@ -290,17 +301,14 @@ type testVectorList struct {
290301}
291302
292303func mustUnhexBigInt (number string ) * big.Int {
293- data , err := hex .DecodeString (number )
294- if err != nil {
295- panic (err )
296- }
297-
304+ data := mustUnhex (number )
298305 value := new (big.Int )
299306 value .SetBytes (data )
300307 return value
301308}
302309
303310func mustUnhex (value string ) []byte {
311+ value = strings .TrimPrefix (value , "0x" )
304312 data , err := hex .DecodeString (value )
305313 if err != nil {
306314 panic (err )
@@ -322,14 +330,18 @@ func (tv *testVector) UnmarshalJSON(data []byte) error {
322330 return err
323331 }
324332
333+ tv .name = raw .Name
325334 tv .p = mustUnhexBigInt (raw .P )
326335 tv .q = mustUnhexBigInt (raw .Q )
327336 tv .n = mustUnhexBigInt (raw .N )
328337 tv .e = mustUnhexInt (raw .E )
329338 tv .d = mustUnhexBigInt (raw .D )
330339 tv .msg = mustUnhex (raw .Msg )
340+ tv .msgPrefix = mustUnhex (raw .MsgPrefix )
341+ tv .inputMsg = mustUnhex (raw .InputMsg )
331342 tv .salt = mustUnhex (raw .Salt )
332- tv .encodedMessage = mustUnhex (raw .EncodedMsg )
343+ tv .saltLen = mustUnhexInt (raw .SaltLen )
344+ tv .isRandomized = mustUnhexInt (raw .IsRandomized ) != 0
333345 tv .blindedMessage = mustUnhex (raw .BlindedMessage )
334346 tv .blindInverse = mustUnhexBigInt (raw .Inv )
335347 tv .blindSig = mustUnhex (raw .BlindSig )
@@ -356,16 +368,11 @@ func (tvl *testVectorList) UnmarshalJSON(data []byte) error {
356368}
357369
358370func verifyTestVector (t * testing.T , vector testVector ) {
359- key , err := loadPrivateKey ()
360- if err != nil {
361- t .Fatal (err )
362- }
363-
371+ key := new (rsa.PrivateKey )
364372 key .PublicKey .N = vector .n
365373 key .PublicKey .E = vector .e
366374 key .D = vector .d
367- key .Primes [0 ] = vector .p
368- key .Primes [1 ] = vector .q
375+ key .Primes = []* big.Int {vector .p , vector .q }
369376 key .Precomputed .Dp = nil // Remove precomputed CRT values
370377
371378 // Recompute the original blind
@@ -376,34 +383,56 @@ func verifyTestVector(t *testing.T, vector testVector) {
376383 }
377384
378385 signer := NewSigner (key )
379- verifier := NewVerifier (& key .PublicKey , crypto .SHA384 )
380386
381- blindedMsg , state , err := fixedBlind (vector .msg , vector .salt , r , rInv , & key .PublicKey , verifier .Hash ())
382- if err != nil {
383- t .Fatal (err )
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" )
384397 }
385398
386- blindSig , err := signer .BlindSign (blindedMsg )
387- if err != nil {
388- t .Fatal (err )
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 )
389404 }
390405
391- sig , err := state .Finalize (blindSig )
392- if err != nil {
393- t .Fatal (err )
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 )
394412 }
395413
396- if ! bytes .Equal (state .encodedMsg , vector .encodedMessage ) {
397- t .Errorf ("Encoded message mismatch: expected %x, got %x" , state .encodedMsg , vector .encodedMessage )
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 )
398420 }
399421
400- if ! bytes .Equal (sig , vector .sig ) {
401- t .Errorf ("Signature mismatch: expected %x, got %x" , sig , vector .sig )
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 )
402428 }
429+
430+ err = verifier .Verify (inputMsg , sig )
431+ test .CheckNoErr (t , err , "verification failed" )
403432}
404433
405434func TestVectors (t * testing.T ) {
406- data , err := os .ReadFile ("testdata/test_vectors .json" )
435+ data , err := os .ReadFile ("testdata/test_vectors_rfc9474 .json" )
407436 if err != nil {
408437 t .Fatal ("Failed reading test vectors:" , err )
409438 }
@@ -415,7 +444,9 @@ func TestVectors(t *testing.T) {
415444 }
416445
417446 for _ , vector := range tvl .vectors {
418- verifyTestVector (t , vector )
447+ t .Run (vector .name , func (tt * testing.T ) {
448+ verifyTestVector (tt , vector )
449+ })
419450 }
420451}
421452
@@ -463,3 +494,48 @@ func BenchmarkBRSA(b *testing.B) {
463494 b .Fatal (err )
464495 }
465496}
497+
498+ func Example_blindrsa () {
499+ // Setup (offline)
500+
501+ // Server: generate an RSA keypair.
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+ // Client: stores Server's public key.
511+ verifier := NewVerifier (pk , crypto .SHA384 )
512+
513+ // Protocol (online)
514+
515+ // Client blinds a message.
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+ // Server signs a blinded message, and produces a blinded signature.
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+ // Client builds a signature from the previous state and the blinded signature.
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+ // Client verifies the signature is valid.
538+ ok := verifier .Verify (msg , signature )
539+ fmt .Printf ("Valid signature: %v" , ok == nil )
540+ // Output: Valid signature: true
541+ }
0 commit comments