github.com/cloudflare/circl@v1.5.0/tss/rsa/rsa_threshold_test.go (about) 1 package rsa 2 3 import ( 4 "bytes" 5 "crypto" 6 "crypto/rand" 7 "crypto/rsa" 8 _ "crypto/sha256" 9 "errors" 10 "fmt" 11 "io" 12 "math/big" 13 "testing" 14 15 "github.com/cloudflare/circl/internal/test" 16 ) 17 18 var ONE = big.NewInt(1) 19 20 func TestGenerateKey(t *testing.T) { 21 // [Warning]: this is only for tests, use a secure bitlen above 2048 bits. 22 bitlen := 128 23 key, err := GenerateKey(rand.Reader, bitlen) 24 test.CheckNoErr(t, err, "failed to create key") 25 test.CheckOk(key.Validate() == nil, fmt.Sprintf("key is not valid: %v", key), t) 26 } 27 28 func createPrivateKey(p, q *big.Int, e int) *rsa.PrivateKey { 29 return &rsa.PrivateKey{ 30 PublicKey: rsa.PublicKey{ 31 E: e, 32 }, 33 D: nil, 34 Primes: []*big.Int{p, q}, 35 Precomputed: rsa.PrecomputedValues{}, 36 } 37 } 38 39 func TestCalcN(t *testing.T) { 40 TWO := big.NewInt(2) 41 n := calcN(ONE, TWO) 42 if n.Cmp(TWO) != 0 { 43 t.Fatal("calcN failed: (1, 2)") 44 } 45 n = calcN(TWO, big.NewInt(4)) 46 if n.Cmp(big.NewInt(8)) != 0 { 47 t.Fatal("calcN failed: (2, 4)") 48 } 49 } 50 51 func TestComputePolynomial(t *testing.T) { 52 m := big.NewInt(11) 53 const k = 5 54 a := make([]*big.Int, k) 55 for i := 0; i < k; i++ { 56 a[i] = big.NewInt(int64(i + 1)) 57 } 58 // a = {1, 2, 3, 4, 5} 59 60 x := uint(3) 61 out := computePolynomial(k, a, x, m) 62 // 1 * 3^0 = 1 = 1 63 // 2 * 3^1 = 6 = 6 64 // 3 * 3^2 = 27 = 5 65 // 4 * 3^3 = 108 = 9 66 // 5 * 3^4 = 405 = 9 67 // 1 + 6 + 5 + 9 + 9 = 30 = 8 68 if out.Cmp(big.NewInt(8)) != 0 { 69 t.Fatal("compute polynomial failed") 70 } 71 } 72 73 func TestComputeLambda(t *testing.T) { 74 // shares = {1, 2, 3, 4, 5} 75 // i = 0 76 // ∆ = 5! = 120 77 // j = 3 78 // 79 // num = (0 - 1) * (0 - 2) * (0 - 4) * (0 - 5) = 40 80 // dem = (3 - 1) * (3 - 2) * (3 - 4) * (3 - 5) = 4 81 // num/dev = 40/4 = 10 82 // ∆ * 10 = 120 * 10 = 1200 83 shares := make([]SignShare, 5) 84 for i := uint(1); i <= 5; i++ { 85 shares[i-1].Index = i 86 } 87 i := int64(0) 88 delta := int64(120) 89 j := int64(3) 90 91 lambda, err := computeLambda(big.NewInt(delta), shares, i, j) 92 93 if err != nil || lambda.Cmp(big.NewInt(1200)) != 0 { 94 t.Fatal("computeLambda failed") 95 } 96 } 97 98 func TestDeal(t *testing.T) { 99 // Players = 3 100 // Threshold = 2 101 // e = 3 102 // p' = 11 103 // q' = 5 104 // p = 2(11) + 1 = 23 105 // q = 2(5) + 1 = 11 106 // n = 253 107 // m = 55 108 // d = 37 109 // 110 // a[0] = 37 111 // a[1] = 33 112 // 113 // 114 // Index = 1 115 // computePolynomial(k: 2, a: {37, 33}, x: 1, m: 55) : 116 // 37 * 1^0 = 37 * 1 = 37 117 // 33 * 1^1 = 33 * 1 = 33 118 // 37 + 33 = 70 = 15 119 // 120 // shares[0].si = 15 121 // shares[0].Index = 1 122 // 123 // Index = 2 124 // computePolynomial(k: 2, a: {37, 33}, x: 2, m: 55) : 125 // 37 * 2^0 = 37 * 1 = 37 126 // 33 * 2^1 = 33 * 2 = 66 = 11 127 // 37 + 11 = 48 128 // 129 // shares[1].si = 48 130 // shares[1].Index = 2 131 // 132 // 133 // Index = 3 134 // computePolynomial(k: 2, a: {37, 33}, x: 3, m: 55) : 135 // 37 * 3^0 = 37 * 1 = 37 136 // 33 * 3^1 = 33 * 3 = 99 = 44 137 // 37 + 44 = 81 = 26 138 // 139 // shares[2].si = 26 140 // shares[2].Index = 3 141 // 142 // 143 // 144 r := bytes.NewReader([]byte{33, 17}) 145 players := uint(3) 146 threshold := uint(2) 147 p := int64(23) 148 q := int64(11) 149 e := 3 150 151 key := createPrivateKey(big.NewInt(p), big.NewInt(q), e) 152 153 share, err := Deal(r, players, threshold, key, false) 154 if err != nil { 155 t.Fatal(err) 156 } 157 if share[0].si.Cmp(big.NewInt(15)) != 0 { 158 t.Fatalf("share[0].si should have been 15 but was %d", share[0].si) 159 } 160 if share[1].si.Cmp(big.NewInt(48)) != 0 { 161 t.Fatalf("share[1].si should have been 48 but was %d", share[1].si) 162 } 163 if share[2].si.Cmp(big.NewInt(26)) != 0 { 164 t.Fatalf("share[2].si should have been 26 but was %d", share[2].si) 165 } 166 } 167 168 const ( 169 PKS1v15 = 0 170 PSS = 1 171 ) 172 173 func testIntegration(t *testing.T, algo crypto.Hash, priv *rsa.PrivateKey, threshold uint, keys []KeyShare, padScheme int) { 174 msg := []byte("hello") 175 pub := &priv.PublicKey 176 177 var padder Padder 178 if padScheme == PKS1v15 { 179 padder = &PKCS1v15Padder{} 180 } else if padScheme == PSS { 181 padder = &PSSPadder{ 182 Rand: rand.Reader, 183 Opts: nil, 184 } 185 } else { 186 t.Fatal(errors.New("unknown padScheme")) 187 } 188 189 msgPH, err := PadHash(padder, algo, pub, msg) 190 if err != nil { 191 t.Fatal(err) 192 } 193 194 signshares := make([]SignShare, threshold) 195 196 for i := uint(0); i < threshold; i++ { 197 signshares[i], err = keys[i].Sign(rand.Reader, pub, msgPH, true) 198 if err != nil { 199 t.Fatal(err) 200 } 201 } 202 203 sig, err := CombineSignShares(pub, signshares, msgPH) 204 if err != nil { 205 t.Fatal(err) 206 } 207 if len(sig) != pub.Size() { 208 t.Fatal("bad signature size") 209 } 210 211 h := algo.New() 212 h.Write(msg) 213 hashed := h.Sum(nil) 214 215 if padScheme == PKS1v15 { 216 err = rsa.VerifyPKCS1v15(pub, algo, hashed, sig) 217 } else if padScheme == PSS { 218 err = rsa.VerifyPSS(pub, algo, hashed, sig, padder.(*PSSPadder).Opts) 219 } else { 220 panic("logical error") 221 } 222 223 if err != nil { 224 t.Logf("d: %v p: %v q: %v\n", priv.D.Text(16), priv.Primes[0].Text(16), priv.Primes[1].Text(16)) 225 for i, k := range keys { 226 t.Logf("keys[%v]: %v\n", i, k) 227 } 228 for i, s := range signshares { 229 t.Logf("signShares[%v]: %v\n", i, s) 230 } 231 t.Logf("sig: %x\n", sig) 232 t.Fatal(err) 233 } 234 } 235 236 func TestIntegrationStdRsaKeyGenerationPKS1v15(t *testing.T) { 237 const players = 3 238 const threshold = 2 239 const bits = 2048 240 const algo = crypto.SHA256 241 242 key, err := rsa.GenerateKey(rand.Reader, bits) 243 if err != nil { 244 t.Fatal(err) 245 } 246 keys, err := Deal(rand.Reader, players, threshold, key, false) 247 if err != nil { 248 t.Fatal(err) 249 } 250 testIntegration(t, algo, key, threshold, keys, PKS1v15) 251 } 252 253 func TestIntegrationStdRsaKeyGenerationPSS(t *testing.T) { 254 const players = 3 255 const threshold = 2 256 const bits = 2048 257 const algo = crypto.SHA256 258 259 key, err := rsa.GenerateKey(rand.Reader, bits) 260 if err != nil { 261 t.Fatal(err) 262 } 263 keys, err := Deal(rand.Reader, players, threshold, key, false) 264 if err != nil { 265 t.Fatal(err) 266 } 267 testIntegration(t, algo, key, threshold, keys, PSS) 268 } 269 270 // nolint: unparam 271 func benchmarkSignCombineHelper(randSource io.Reader, parallel bool, b *testing.B, players, threshold uint, bits int, algo crypto.Hash, padScheme int) { 272 key, err := rsa.GenerateKey(rand.Reader, bits) 273 pub := key.PublicKey 274 if err != nil { 275 panic(err) 276 } 277 278 keys, err := Deal(rand.Reader, players, threshold, key, true) 279 if err != nil { 280 b.Fatal(err) 281 } 282 283 msg := []byte("hello") 284 var padder Padder 285 if padScheme == PKS1v15 { 286 padder = &PKCS1v15Padder{} 287 } else if padScheme == PSS { 288 padder = &PSSPadder{ 289 Rand: rand.Reader, 290 Opts: nil, 291 } 292 } else { 293 b.Fatal(errors.New("unknown padScheme")) 294 } 295 msgPH, err := PadHash(padder, algo, &pub, msg) 296 if err != nil { 297 b.Fatal(err) 298 } 299 300 signshares := make([]SignShare, threshold) 301 b.ResetTimer() 302 for i := 0; i < b.N; i++ { 303 for i := uint(0); i < threshold; i++ { 304 signshares[i], err = keys[i].Sign(randSource, &pub, msgPH, parallel) 305 if err != nil { 306 b.Fatal(err) 307 } 308 } 309 _, err = CombineSignShares(&pub, signshares, msgPH) 310 if err != nil { 311 b.Fatal(err) 312 } 313 } 314 b.StopTimer() 315 } 316 317 func BenchmarkBaselineRSA_SHA256_4096(b *testing.B) { 318 const bits = 4096 319 const algo = crypto.SHA256 320 321 key, err := rsa.GenerateKey(rand.Reader, bits) 322 if err != nil { 323 b.Fatal(err) 324 } 325 h := algo.New() 326 327 msg := []byte("hello") 328 329 h.Write(msg) 330 d := h.Sum(nil) 331 b.ResetTimer() 332 for i := 0; i < b.N; i++ { 333 _, err = rsa.SignPKCS1v15(rand.Reader, key, algo, d) 334 if err != nil { 335 b.Fatal(err) 336 } 337 } 338 b.StopTimer() 339 } 340 341 func BenchmarkBaselineRSA_SHA256_2048(b *testing.B) { 342 const bits = 2048 343 const algo = crypto.SHA256 344 345 key, err := rsa.GenerateKey(rand.Reader, bits) 346 if err != nil { 347 b.Fatal(err) 348 } 349 h := algo.New() 350 351 msg := []byte("hello") 352 353 h.Write(msg) 354 d := h.Sum(nil) 355 b.ResetTimer() 356 for i := 0; i < b.N; i++ { 357 _, err = rsa.SignPKCS1v15(rand.Reader, key, algo, d) 358 if err != nil { 359 b.Fatal(err) 360 } 361 } 362 b.StopTimer() 363 } 364 365 func BenchmarkSignCombine_SHA256_4096_3_2_Scheme(b *testing.B) { 366 const players = 3 367 const threshold = 2 368 const bits = 4096 369 const algo = crypto.SHA256 370 benchmarkSignCombineHelper(nil, false, b, players, threshold, bits, algo, PKS1v15) 371 } 372 373 func BenchmarkSignCombine_SHA256_4096_3_2_Scheme_Blind(b *testing.B) { 374 const players = 3 375 const threshold = 2 376 const bits = 4096 377 const algo = crypto.SHA256 378 benchmarkSignCombineHelper(rand.Reader, false, b, players, threshold, bits, algo, PKS1v15) 379 } 380 381 func BenchmarkSignCombine_SHA256_4096_3_2_Scheme_BlindParallel(b *testing.B) { 382 const players = 3 383 const threshold = 2 384 const bits = 4096 385 const algo = crypto.SHA256 386 benchmarkSignCombineHelper(rand.Reader, true, b, players, threshold, bits, algo, PKS1v15) 387 } 388 389 func BenchmarkSignCombine_SHA256_2048_3_2_Scheme(b *testing.B) { 390 const players = 3 391 const threshold = 2 392 const bits = 2048 393 const algo = crypto.SHA256 394 benchmarkSignCombineHelper(nil, false, b, players, threshold, bits, algo, PKS1v15) 395 } 396 397 func BenchmarkSignCombine_SHA256_2048_3_2_Scheme_Blind(b *testing.B) { 398 const players = 3 399 const threshold = 2 400 const bits = 2048 401 const algo = crypto.SHA256 402 benchmarkSignCombineHelper(rand.Reader, false, b, players, threshold, bits, algo, PKS1v15) 403 } 404 405 func BenchmarkSignCombine_SHA256_2048_3_2_Scheme_BlindParallel(b *testing.B) { 406 const players = 3 407 const threshold = 2 408 const bits = 2048 409 const algo = crypto.SHA256 410 benchmarkSignCombineHelper(rand.Reader, true, b, players, threshold, bits, algo, PKS1v15) 411 } 412 413 func BenchmarkSignCombine_SHA256_1024_3_2_Scheme(b *testing.B) { 414 const players = 3 415 const threshold = 2 416 const bits = 1024 417 const algo = crypto.SHA256 418 benchmarkSignCombineHelper(nil, false, b, players, threshold, bits, algo, PKS1v15) 419 } 420 421 func BenchmarkDealGeneration(b *testing.B) { 422 const players = 3 423 const threshold = 2 424 const bits = 2048 425 key, err := rsa.GenerateKey(rand.Reader, bits) 426 if err != nil { 427 b.Fatal("could not generate key") 428 } 429 b.ResetTimer() 430 for i := 0; i < b.N; i++ { 431 _, err := Deal(rand.Reader, players, threshold, key, false) 432 if err != nil { 433 b.Fatal(err) 434 } 435 } 436 }