github.com/zcqzcg/fabric-ca@v2.0.0-alpha.0.20200416163940-d878ee6db75a+incompatible/lib/server/idemix/enroll_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 package idemix_test 7 8 import ( 9 "crypto/ecdsa" 10 "crypto/elliptic" 11 "crypto/rand" 12 "testing" 13 14 proto "github.com/golang/protobuf/proto" 15 fp256bn "github.com/hyperledger/fabric-amcl/amcl/FP256BN" 16 "github.com/hyperledger/fabric-ca/api" 17 . "github.com/hyperledger/fabric-ca/lib/server/idemix" 18 "github.com/hyperledger/fabric-ca/lib/server/idemix/mocks" 19 "github.com/hyperledger/fabric-ca/util" 20 "github.com/hyperledger/fabric/idemix" 21 "github.com/pkg/errors" 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func TestIdemixEnrollInvalidBasicAuth(t *testing.T) { 26 ctx := new(mocks.ServerRequestCtx) 27 ctx.On("BasicAuthentication").Return("", errors.New("bad credentials")) 28 ctx.On("IsBasicAuth").Return(true) 29 handler := EnrollRequestHandler{Ctx: ctx} 30 _, err := handler.HandleRequest() 31 assert.Error(t, err, "Idemix enroll should fail if basic auth credentials are invalid") 32 } 33 func TestIdemixEnrollInvalidTokenAuth(t *testing.T) { 34 ctx := new(mocks.ServerRequestCtx) 35 ctx.On("TokenAuthentication").Return("", errors.New("bad credentials")) 36 ctx.On("IsBasicAuth").Return(false) 37 handler := EnrollRequestHandler{Ctx: ctx} 38 _, err := handler.HandleRequest() 39 assert.Error(t, err, "Idemix enroll should fail if token auth credentials are invalid") 40 } 41 func TestIdemixEnrollBadReqBody(t *testing.T) { 42 ctx := new(mocks.ServerRequestCtx) 43 ctx.On("BasicAuthentication").Return("foo", nil) 44 ctx.On("IsBasicAuth").Return(true) 45 handler := EnrollRequestHandler{Ctx: ctx} 46 req := api.IdemixEnrollmentRequestNet{} 47 req.CredRequest = nil 48 ctx.On("ReadBody", &req).Return(errors.New("Invalid request body")) 49 _, err := handler.HandleRequest() 50 assert.Error(t, err, "Idemix enroll should return error if reading body fails") 51 } 52 53 func TestHandleIdemixEnrollForNonce(t *testing.T) { 54 ctx := new(mocks.ServerRequestCtx) 55 ctx.On("BasicAuthentication").Return("foo", nil) 56 idemixlib := new(mocks.Lib) 57 rnd, err := idemix.GetRand() 58 if err != nil { 59 t.Fatalf("Error generating a random number") 60 } 61 rmo := idemix.RandModOrder(rnd) 62 idemixlib.On("GetRand").Return(rnd, nil) 63 idemixlib.On("RandModOrder", rnd).Return(rmo) 64 ctx.On("IsBasicAuth").Return(true) 65 req := api.IdemixEnrollmentRequestNet{} 66 req.CredRequest = nil 67 ctx.On("ReadBody", &req).Return(nil) 68 69 issuer := new(mocks.MyIssuer) 70 issuer.On("IdemixRand").Return(rnd) 71 72 nm := new(mocks.NonceManager) 73 nm.On("GetNonce").Return(fp256bn.NewBIG(), nil) 74 issuer.On("NonceManager").Return(nm) 75 handler := EnrollRequestHandler{Ctx: ctx, Issuer: issuer, IdmxLib: idemixlib} 76 _, err = handler.HandleRequest() 77 assert.NoError(t, err, "Idemix enroll should return a valid nonce") 78 } 79 func TestHandleIdemixEnrollForNonceTokenAuth(t *testing.T) { 80 ctx := new(mocks.ServerRequestCtx) 81 ctx.On("TokenAuthentication").Return("foo", nil) 82 83 idemixlib := new(mocks.Lib) 84 rnd, err := idemix.GetRand() 85 if err != nil { 86 t.Fatalf("Error generating a random number") 87 } 88 rmo := idemix.RandModOrder(rnd) 89 idemixlib.On("GetRand").Return(rnd, nil) 90 idemixlib.On("RandModOrder", rnd).Return(rmo) 91 92 ctx.On("IsBasicAuth").Return(false) 93 94 req := api.IdemixEnrollmentRequestNet{} 95 req.CredRequest = nil 96 ctx.On("ReadBody", &req).Return(nil) 97 issuer := new(mocks.MyIssuer) 98 issuer.On("IdemixRand").Return(rnd) 99 100 nm := new(mocks.NonceManager) 101 nm.On("GetNonce").Return(fp256bn.NewBIG(), nil) 102 issuer.On("NonceManager").Return(nm) 103 104 ctx.On("GetIssuer").Return(issuer, nil) 105 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 106 _, err = handler.HandleRequest() 107 assert.NoError(t, err, "Idemix enroll should return a valid nonce") 108 } 109 110 func TestHandleIdemixEnrollForNonceError(t *testing.T) { 111 ctx := new(mocks.ServerRequestCtx) 112 ctx.On("TokenAuthentication").Return("foo", nil) 113 114 idemixlib := new(mocks.Lib) 115 rnd, err := idemix.GetRand() 116 if err != nil { 117 t.Fatalf("Error generating a random number") 118 } 119 rmo := idemix.RandModOrder(rnd) 120 idemixlib.On("GetRand").Return(rnd, nil) 121 idemixlib.On("RandModOrder", rnd).Return(rmo) 122 123 ctx.On("IsBasicAuth").Return(false) 124 125 req := api.IdemixEnrollmentRequestNet{} 126 req.CredRequest = nil 127 ctx.On("ReadBody", &req).Return(nil) 128 issuer := new(mocks.MyIssuer) 129 issuer.On("IdemixRand").Return(rnd) 130 131 nm := new(mocks.NonceManager) 132 nm.On("GetNonce").Return(nil, errors.New("Failed to generate nonce")) 133 issuer.On("NonceManager").Return(nm) 134 135 ctx.On("GetIssuer").Return(issuer, nil) 136 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 137 _, err = handler.HandleRequest() 138 assert.Error(t, err, "Idemix enroll should return an error because NonceManager.GetNonce returned an error") 139 } 140 141 func TestHandleIdemixEnrollForCredentialError(t *testing.T) { 142 ctx := new(mocks.ServerRequestCtx) 143 ctx.On("BasicAuthentication").Return("foo", nil) 144 145 idemixlib := new(mocks.Lib) 146 rnd, err := idemix.GetRand() 147 if err != nil { 148 t.Fatalf("Error generating a random number") 149 } 150 rmo := idemix.RandModOrder(rnd) 151 idemixlib.On("GetRand").Return(rnd, nil) 152 idemixlib.On("RandModOrder", rnd).Return(rmo, nil) 153 154 issuerCred := NewIssuerCredential(testPublicKeyFile, testSecretKeyFile, idemixlib) 155 issuer := new(mocks.MyIssuer) 156 issuer.On("Name").Return("") 157 issuer.On("IssuerCredential").Return(issuerCred) 158 issuer.On("IdemixRand").Return(rnd) 159 160 ctx.On("GetIssuer").Return(issuer, nil) 161 ctx.On("IsBasicAuth").Return(true) 162 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 163 nonce, err := handler.GenerateNonce() 164 if err != nil { 165 t.Fatalf("Failed to generate nonce: %s", err.Error()) 166 } 167 168 credReq, _, err := newIdemixCredentialRequest(t, nonce) 169 if err != nil { 170 t.Fatalf("Failed to create credential request: %s", err.Error()) 171 } 172 f := getReadBodyFunc(t, credReq) 173 req := api.IdemixEnrollmentRequestNet{} 174 ctx.On("ReadBody", &req).Return(f) 175 176 _, err = handler.HandleRequest() 177 assert.Error(t, err, "Idemix enroll should return error if IssuerCredential has not been loaded from disk") 178 if err != nil { 179 assert.Contains(t, err.Error(), "Failed to get Idemix issuer key for the CA") 180 } 181 182 err = issuerCred.Load() 183 if err != nil { 184 t.Fatalf("Failed to load issuer credential") 185 } 186 ctx.On("GetCaller").Return(nil, errors.New("Error when getting caller of the request")) 187 _, err = handler.HandleRequest() 188 assert.Error(t, err, "Idemix enroll should return error if ctx.GetCaller returns error") 189 if err != nil { 190 assert.Contains(t, err.Error(), "Error when getting caller of the request") 191 } 192 } 193 194 func TestHandleIdemixEnrollCheckNonceError(t *testing.T) { 195 ctx := new(mocks.ServerRequestCtx) 196 idemixlib := new(mocks.Lib) 197 rnd, err := idemix.GetRand() 198 if err != nil { 199 t.Fatalf("Error generating a random number") 200 } 201 rmo := idemix.RandModOrder(rnd) 202 idemixlib.On("GetRand").Return(rnd, nil) 203 idemixlib.On("RandModOrder", rnd).Return(rmo) 204 205 issuerCred := NewIssuerCredential(testPublicKeyFile, 206 testSecretKeyFile, idemixlib) 207 err = issuerCred.Load() 208 if err != nil { 209 t.Fatalf("Failed to load issuer credential") 210 } 211 212 rh := fp256bn.NewBIGint(1) 213 ra := new(mocks.RevocationAuthority) 214 ra.On("GetNewRevocationHandle").Return(rh, nil) 215 216 issuer := new(mocks.MyIssuer) 217 issuer.On("Name").Return("") 218 issuer.On("IssuerCredential").Return(issuerCred) 219 issuer.On("IdemixRand").Return(rnd) 220 issuer.On("RevocationAuthority").Return(ra) 221 222 ctx.On("IsBasicAuth").Return(true) 223 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 224 nm := new(mocks.NonceManager) 225 nonce := idemix.RandModOrder(rnd) 226 nm.On("GetNonce").Return(nonce, nil) 227 nm.On("CheckNonce", nonce).Return(errors.New("Invalid nonce")) 228 issuer.On("NonceManager").Return(nm) 229 230 caller := new(mocks.User) 231 caller.On("Name").Return("foo") 232 233 credReq, _, err := newIdemixCredentialRequest(t, nonce) 234 if err != nil { 235 t.Fatalf("Failed to create test credential request") 236 } 237 238 ctx.On("BasicAuthentication").Return("foo", nil) 239 f := getReadBodyFunc(t, credReq) 240 ctx.On("ReadBody", &api.IdemixEnrollmentRequestNet{}).Return(f) 241 ctx.On("GetCA").Return(issuer, nil) 242 ctx.On("GetCaller").Return(caller, nil) 243 244 // Now setup of all mocks is over, test the method 245 _, err = handler.HandleRequest() 246 assert.Error(t, err, "Idemix enroll should return error because NonceManager.CheckNonce returned error") 247 } 248 249 func TestHandleIdemixEnrollNewCredError(t *testing.T) { 250 ctx := new(mocks.ServerRequestCtx) 251 idemixlib := new(mocks.Lib) 252 rnd, err := idemix.GetRand() 253 if err != nil { 254 t.Fatalf("Error generating a random number") 255 } 256 rmo := idemix.RandModOrder(rnd) 257 idemixlib.On("GetRand").Return(rnd, nil) 258 idemixlib.On("RandModOrder", rnd).Return(rmo) 259 260 issuerCred := NewIssuerCredential(testPublicKeyFile, 261 testSecretKeyFile, idemixlib) 262 err = issuerCred.Load() 263 if err != nil { 264 t.Fatalf("Failed to load issuer credential") 265 } 266 ik, _ := issuerCred.GetIssuerKey() 267 268 rh := fp256bn.NewBIGint(1) 269 ra := new(mocks.RevocationAuthority) 270 ra.On("GetNewRevocationHandle").Return(rh, nil) 271 272 issuer := new(mocks.MyIssuer) 273 issuer.On("Name").Return("") 274 issuer.On("IssuerCredential").Return(issuerCred) 275 issuer.On("IdemixRand").Return(rnd) 276 issuer.On("RevocationAuthority").Return(ra) 277 278 ctx.On("IsBasicAuth").Return(true) 279 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 280 nm := new(mocks.NonceManager) 281 nonce := idemix.RandModOrder(rnd) 282 nm.On("GetNonce").Return(nonce, nil) 283 nm.On("CheckNonce", nonce).Return(nil) 284 issuer.On("NonceManager").Return(nm) 285 286 caller := new(mocks.User) 287 caller.On("GetName").Return("foo") 288 caller.On("GetAffiliationPath").Return([]string{"a", "b", "c"}) 289 caller.On("GetAttribute", "role").Return(&api.Attribute{Name: "role", Value: "2"}, nil) 290 caller.On("LoginComplete").Return(nil) 291 292 credReq, _, err := newIdemixCredentialRequest(t, nonce) 293 if err != nil { 294 t.Fatalf("Failed to create test credential request") 295 } 296 _, attrs, err := handler.GetAttributeValues(caller, ik.Ipk, rh) 297 if err != nil { 298 t.Fatalf("Failed to get attributes") 299 } 300 301 idemixlib.On("NewCredential", ik, credReq, attrs, rnd).Return(nil, errors.New("Failed to create credential")) 302 303 ctx.On("BasicAuthentication").Return("foo", nil) 304 f := getReadBodyFunc(t, credReq) 305 ctx.On("ReadBody", &api.IdemixEnrollmentRequestNet{}).Return(f) 306 ctx.On("GetCA").Return(issuer, nil) 307 ctx.On("GetCaller").Return(caller, nil) 308 309 // Now setup of all mocks is over, test the method 310 _, err = handler.HandleRequest() 311 assert.Error(t, err, "Idemix enroll should return error because idemix.NewCredential returned error") 312 } 313 314 func TestHandleIdemixEnrollInsertCredError(t *testing.T) { 315 ctx := new(mocks.ServerRequestCtx) 316 idemixlib := new(mocks.Lib) 317 rnd, err := idemix.GetRand() 318 if err != nil { 319 t.Fatalf("Error generating a random number") 320 } 321 rmo := idemix.RandModOrder(rnd) 322 idemixlib.On("GetRand").Return(rnd, nil) 323 idemixlib.On("RandModOrder", rnd).Return(rmo) 324 325 issuerCred := NewIssuerCredential(testPublicKeyFile, 326 testSecretKeyFile, idemixlib) 327 err = issuerCred.Load() 328 if err != nil { 329 t.Fatalf("Failed to load issuer credential") 330 } 331 ik, _ := issuerCred.GetIssuerKey() 332 333 rh := fp256bn.NewBIGint(1) 334 ra := new(mocks.RevocationAuthority) 335 ra.On("GetNewRevocationHandle").Return(rh, nil) 336 337 issuer := new(mocks.MyIssuer) 338 issuer.On("Name").Return("") 339 issuer.On("IssuerCredential").Return(issuerCred) 340 issuer.On("IdemixRand").Return(rnd) 341 issuer.On("RevocationAuthority").Return(ra) 342 343 ctx.On("IsBasicAuth").Return(true) 344 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 345 nm := new(mocks.NonceManager) 346 nonce := idemix.RandModOrder(rnd) 347 nm.On("GetNonce").Return(nonce, nil) 348 nm.On("CheckNonce", nonce).Return(nil) 349 350 caller := new(mocks.User) 351 caller.On("GetName").Return("foo") 352 caller.On("GetAffiliationPath").Return([]string{"a", "b", "c"}) 353 caller.On("GetAttribute", "role").Return(&api.Attribute{Name: "role", Value: "2"}, nil) 354 caller.On("LoginComplete").Return(nil) 355 356 credReq, _, err := newIdemixCredentialRequest(t, nonce) 357 if err != nil { 358 t.Fatalf("Failed to create test credential request") 359 } 360 _, attrs, err := handler.GetAttributeValues(caller, ik.Ipk, rh) 361 if err != nil { 362 t.Fatalf("Failed to get attributes") 363 } 364 cred, err := idemix.NewCredential(ik, credReq, attrs, rnd) 365 if err != nil { 366 t.Fatalf("Failed to create credential") 367 } 368 idemixlib.On("NewCredential", ik, credReq, attrs, rnd).Return(cred, nil) 369 370 b64CredBytes, err := getB64EncodedCred(cred) 371 if err != nil { 372 t.Fatalf("Failed to base64 encode credential") 373 } 374 credAccessor := new(mocks.CredDBAccessor) 375 credAccessor.On("InsertCredential", 376 CredRecord{RevocationHandle: util.B64Encode(idemix.BigToBytes(fp256bn.NewBIGint(1))), 377 CALabel: "", ID: "foo", Status: "good", 378 Cred: b64CredBytes}).Return(errors.New("Failed to add credential to DB")) 379 380 issuer.On("CredDBAccessor").Return(credAccessor, nil) 381 issuer.On("NonceManager").Return(nm) 382 383 ctx.On("BasicAuthentication").Return("foo", nil) 384 f := getReadBodyFunc(t, credReq) 385 ctx.On("ReadBody", &api.IdemixEnrollmentRequestNet{}).Return(f) 386 ctx.On("GetCA").Return(issuer, nil) 387 ctx.On("GetCaller").Return(caller, nil) 388 389 // Now setup of all mocks is over, test the method 390 _, err = handler.HandleRequest() 391 assert.Error(t, err, "Idemix enroll should return error because CredDBAccessor.InsertCredentail returned error") 392 } 393 394 func TestHandleIdemixEnrollForCredentialSuccess(t *testing.T) { 395 ctx := new(mocks.ServerRequestCtx) 396 idemixlib := new(mocks.Lib) 397 rnd, err := idemix.GetRand() 398 if err != nil { 399 t.Fatalf("Error generating a random number") 400 } 401 rmo := idemix.RandModOrder(rnd) 402 idemixlib.On("GetRand").Return(rnd, nil) 403 idemixlib.On("RandModOrder", rnd).Return(rmo) 404 405 issuerCred := NewIssuerCredential(testPublicKeyFile, 406 testSecretKeyFile, idemixlib) 407 err = issuerCred.Load() 408 if err != nil { 409 t.Fatalf("Failed to load issuer credential") 410 } 411 ik, _ := issuerCred.GetIssuerKey() 412 413 rh := fp256bn.NewBIGint(1) 414 ra := new(mocks.RevocationAuthority) 415 ra.On("GetNewRevocationHandle").Return(rh, nil) 416 417 issuer := new(mocks.MyIssuer) 418 issuer.On("Name").Return("") 419 issuer.On("IssuerCredential").Return(issuerCred) 420 issuer.On("IdemixRand").Return(rnd) 421 issuer.On("RevocationAuthority").Return(ra) 422 423 ctx.On("IsBasicAuth").Return(true) 424 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib, Issuer: issuer} 425 nm := new(mocks.NonceManager) 426 nonce := idemix.RandModOrder(rnd) 427 nm.On("GetNonce").Return(nonce, nil) 428 nm.On("CheckNonce", nonce).Return(nil) 429 430 caller := new(mocks.User) 431 caller.On("GetName").Return("foo") 432 caller.On("GetAffiliationPath").Return([]string{"a", "b", "c"}) 433 caller.On("GetAttribute", "role").Return(&api.Attribute{Name: "role", Value: "2"}, nil) 434 caller.On("LoginComplete").Return(nil) 435 436 credReq, _, err := newIdemixCredentialRequest(t, nonce) 437 if err != nil { 438 t.Fatalf("Failed to create test credential request") 439 } 440 _, attrs, err := handler.GetAttributeValues(caller, ik.Ipk, rh) 441 if err != nil { 442 t.Fatalf("Failed to get attributes") 443 } 444 cred, err := idemix.NewCredential(ik, credReq, attrs, rnd) 445 if err != nil { 446 t.Fatalf("Failed to create credential") 447 } 448 idemixlib.On("NewCredential", ik, credReq, attrs, rnd).Return(cred, nil) 449 450 b64CredBytes, err := getB64EncodedCred(cred) 451 if err != nil { 452 t.Fatalf("Failed to base64 encode credential") 453 } 454 credAccessor := new(mocks.CredDBAccessor) 455 credAccessor.On("InsertCredential", CredRecord{ 456 RevocationHandle: util.B64Encode(idemix.BigToBytes(fp256bn.NewBIGint(1))), 457 CALabel: "", ID: "foo", Status: "good", Cred: b64CredBytes}).Return(nil) 458 459 issuer.On("CredDBAccessor").Return(credAccessor, nil) 460 issuer.On("NonceManager").Return(nm) 461 462 cri, err := createCRI(t) 463 if err != nil { 464 t.Fatalf("Failed to create CRI: %s", err.Error()) 465 } 466 ra.On("CreateCRI").Return(cri, nil) 467 468 ctx.On("BasicAuthentication").Return("foo", nil) 469 f := getReadBodyFunc(t, credReq) 470 ctx.On("ReadBody", &api.IdemixEnrollmentRequestNet{}).Return(f) 471 ctx.On("GetCA").Return(issuer, nil) 472 ctx.On("GetCaller").Return(caller, nil) 473 474 // Now setup of all mocks is over, test the method 475 _, err = handler.HandleRequest() 476 assert.NoError(t, err) 477 } 478 479 func TestGetAttributeValues(t *testing.T) { 480 ctx := new(mocks.ServerRequestCtx) 481 idemixlib := new(mocks.Lib) 482 ctx.On("IsBasicAuth").Return(true) 483 handler := EnrollRequestHandler{Ctx: ctx, IdmxLib: idemixlib} 484 485 caller := new(mocks.User) 486 caller.On("GetName").Return("foo") 487 caller.On("GetAffiliationPath").Return([]string{"a", "b", "c"}) 488 caller.On("GetAttribute", "role").Return(&api.Attribute{Name: "role", Value: "2"}, nil) 489 caller.On("GetAttribute", "type").Return(&api.Attribute{Name: "type", Value: "client"}, nil) 490 caller.On("LoginComplete").Return(nil) 491 492 rh := fp256bn.NewBIGint(1) 493 494 attrNames := GetAttributeNames() 495 attrNames = append(attrNames, "type") 496 ipk := idemix.IssuerPublicKey{AttributeNames: attrNames} 497 _, _, err := handler.GetAttributeValues(caller, &ipk, rh) 498 assert.NoError(t, err) 499 } 500 501 func createCRI(t *testing.T) (*idemix.CredentialRevocationInformation, error) { 502 key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 503 if err != nil { 504 return nil, err 505 } 506 rnd, err := idemix.GetRand() 507 if err != nil { 508 return nil, err 509 } 510 return idemix.CreateCRI(key, []*fp256bn.BIG{}, 1, idemix.ALG_NO_REVOCATION, rnd) 511 } 512 513 func getB64EncodedCred(cred *idemix.Credential) (string, error) { 514 credBytes, err := proto.Marshal(cred) 515 if err != nil { 516 return "", errors.New("Failed to marshal credential to bytes") 517 } 518 b64CredBytes := util.B64Encode(credBytes) 519 return b64CredBytes, nil 520 } 521 522 func getReadBodyFunc(t *testing.T, credReq *idemix.CredRequest) func(body interface{}) error { 523 return func(body interface{}) error { 524 enrollReq, _ := body.(*api.IdemixEnrollmentRequestNet) 525 if credReq == nil { 526 return errors.New("Error reading the body") 527 } 528 enrollReq.CredRequest = credReq 529 return nil 530 } 531 } 532 533 func newIdemixCredentialRequest(t *testing.T, nonce *fp256bn.BIG) (*idemix.CredRequest, *fp256bn.BIG, error) { 534 idmxlib := new(mocks.Lib) 535 issuerCred := NewIssuerCredential(testPublicKeyFile, testSecretKeyFile, idmxlib) 536 err := issuerCred.Load() 537 if err != nil { 538 t.Fatalf("Failed to load issuer credential") 539 } 540 ik, err := issuerCred.GetIssuerKey() 541 if err != nil { 542 t.Fatalf("Issuer credential returned error while getting issuer key") 543 } 544 rng, err := idemix.GetRand() 545 if err != nil { 546 return nil, nil, err 547 } 548 sk := idemix.RandModOrder(rng) 549 return idemix.NewCredRequest(sk, idemix.BigToBytes(nonce), ik.Ipk, rng), sk, nil 550 }