Skip to content
This repository has been archived by the owner on May 21, 2022. It is now read-only.

Allocation optimization #455

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Commits on Feb 27, 2021

  1. Test to ensure ECDSA signature is valid

    Add assertions to ensure ECDSA signing methods return valid signatures.
    
    This is probably covered elsewhere as well, but putting it in
    ecdsa_test.go makes it more obvious and easier to find.
    jkanywhere committed Feb 27, 2021
    Configuration menu
    Copy the full SHA
    d9e1c41 View commit details
    Browse the repository at this point in the history
  2. Benchmark ECDSA signing methods

    Add benchmark coverage of ECDSA signing methods.
    
    Benchmarks are run using the existing helper for comparability with
    existing benchmarks.
    
    Sign method is also tested directly, to avoid the overhead of *Token.
    
    Report allocations for all benchmarks.
    
    Allocation count for ES384 and ES512 fluctuate across test runs, the
    other singing consistently report the same number of allocations.
    
    Sample output:
    ```
    $ go test -bench=Bench -run=NONE .
    2021/02/26 18:18:30 Listening...
    goos: darwin
    goarch: amd64
    pkg: github.com/dgrijalva/jwt-go
    BenchmarkECDSASigning/Basic_ES256-8                   	  190572	      6702 ns/op	    4249 B/op	      65 allocs/op
    BenchmarkECDSASigning/Basic_ES256/sign-only-8         	   47383	     24650 ns/op	    3329 B/op	      43 allocs/op
    BenchmarkECDSASigning/Basic_ES384-8                   	    1113	   1252975 ns/op	 1750744 B/op	   14474 allocs/op
    BenchmarkECDSASigning/Basic_ES384/sign-only-8         	     286	   3937773 ns/op	 1746175 B/op	   14423 allocs/op
    BenchmarkECDSASigning/Basic_ES512-8                   	     662	   1949937 ns/op	 3028386 B/op	   19608 allocs/op
    BenchmarkECDSASigning/Basic_ES512/sign-only-8         	     170	   6856189 ns/op	 3025471 B/op	   19571 allocs/op
    BenchmarkECDSASigning/basic_ES256_invalid:_foo_=>_bar-8         	  190638	      6665 ns/op	    4249 B/op	      65 allocs/op
    BenchmarkHS256Signing-8                                	 1000000	      1024 ns/op	    1584 B/op	      32 allocs/op
    BenchmarkHS384Signing-8                                	  917286	      1447 ns/op	    1969 B/op	      32 allocs/op
    BenchmarkHS512Signing-8                                	  827744	      1470 ns/op	    2065 B/op	      32 allocs/op
    BenchmarkRS256Signing-8                                	    3037	    390077 ns/op	   32576 B/op	     136 allocs/op
    BenchmarkRS384Signing-8                                	    2976	    379155 ns/op	   32684 B/op	     136 allocs/op
    BenchmarkRS512Signing-8                                	    3205	    388628 ns/op	   32704 B/op	     136 allocs/op
    ```
    jkanywhere committed Feb 27, 2021
    Configuration menu
    Copy the full SHA
    fa71ffb View commit details
    Browse the repository at this point in the history
  3. Reduce allocations during ECDSA signing

    Reduce the number of byte arrays allocated by using big.Int.FillBytes
    when calculating ECDSA signature.
    
    After this change, Benchmarks of ES256 signing method consistently
    report 4 fewer allocations.
    
    Before:
    ```
    BenchmarkECDSASigning/Basic_ES256-8              190572         6702 ns/op       4249 B/op         65 allocs/op
    BenchmarkECDSASigning/Basic_ES256/sign-only-8     47383        24650 ns/op       3329 B/op         43 allocs/op
    ```
    
    After:
    ```
    BenchmarkECDSASigning/Basic_ES256-8              187682         6725 ns/op       4121 B/op         61 allocs/op
    BenchmarkECDSASigning/Basic_ES256/sign-only-8     48656        24446 ns/op       3201 B/op         39 allocs/op
    ```
    jkanywhere committed Feb 27, 2021
    Configuration menu
    Copy the full SHA
    0866ae7 View commit details
    Browse the repository at this point in the history
  4. Use base64.RawURLEncoding to avoid padding

    JWT uses a non-padded base64 encoding.
    
    Current code uses base64.URLEncoding to generate a padded string and
    then removes the padding.
    Likewise, current code adds padding before decoding.
    
    Instead, use base64.RawURLEncoding which does not add or require the
    padding in the first place.
    
    In addition to making the code cleaner, this reduces memory allocations
    as reported by benchmarks.
    
    Before:
    ```
    BenchmarkECDSASigning/Basic_ES256-8                     191396         6917 ns/op       4121 B/op         61 allocs/op
    BenchmarkECDSASigning/Basic_ES256/sign-only-8            49347        25039 ns/op       3201 B/op         39 allocs/op
    BenchmarkECDSASigning/basic_ES256_invalid:_foo_=>_bar-8 190668         6586 ns/op       4121 B/op         61 allocs/op
    BenchmarkHS256Signing-8                                1260060         1131 ns/op       1585 B/op         32 allocs/op
    BenchmarkHS384Signing-8                                 861378         1387 ns/op       1969 B/op         32 allocs/op
    BenchmarkHS512Signing-8                                 896745         1463 ns/op       2065 B/op         32 allocs/op
    BenchmarkRS256Signing-8                                   3086       355769 ns/op      32576 B/op        136 allocs/op
    BenchmarkRS384Signing-8                                   3414       353570 ns/op      32694 B/op        136 allocs/op
    BenchmarkRS512Signing-8                                   3235       349394 ns/op      32706 B/op        136 allocs/op
    ```
    
    After:
    ```
    BenchmarkECDSASigning/Basic_ES256-8                     176617         6827 ns/op       4021 B/op         58 allocs/op
    BenchmarkECDSASigning/Basic_ES256/sign-only-8            48038        24213 ns/op       3169 B/op         38 allocs/op
    BenchmarkECDSASigning/basic_ES256_invalid:_foo_=>_bar-8 194352         6928 ns/op       4021 B/op         58 allocs/op
    BenchmarkHS256Signing-8                                1000000         1127 ns/op       1488 B/op         29 allocs/op
    BenchmarkHS384Signing-8                                 972552         1369 ns/op       1873 B/op         29 allocs/op
    BenchmarkHS512Signing-8                                 780751         1368 ns/op       1969 B/op         29 allocs/op
    BenchmarkRS256Signing-8                                   3014       387326 ns/op      32475 B/op        133 allocs/op
    BenchmarkRS384Signing-8                                   3044       361411 ns/op      32591 B/op        133 allocs/op
    BenchmarkRS512Signing-8                                   3273       355504 ns/op      32607 B/op        133 allocs/op
    ```
    
    Benchmarks of signing methods ES384 and ES512 are omitted because their
    allocations are not consistent.
    jkanywhere committed Feb 27, 2021
    Configuration menu
    Copy the full SHA
    efac53c View commit details
    Browse the repository at this point in the history