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