rbsecp256k1 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -3
- data/Rakefile +2 -0
- data/documentation/context.md +20 -5
- data/documentation/index.md +13 -13
- data/documentation/private_key.md +1 -1
- data/documentation/public_key.md +2 -2
- data/documentation/signature.md +2 -2
- data/ext/rbsecp256k1/extconf.rb +9 -55
- data/ext/rbsecp256k1/rbsecp256k1.c +140 -128
- data/lib/rbsecp256k1.rb +3 -0
- data/lib/rbsecp256k1/context.rb +29 -0
- data/lib/rbsecp256k1/util.rb +2 -0
- data/lib/rbsecp256k1/version.rb +3 -1
- metadata +6 -5
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: '09bce1370a196e16d15f8d923add9097a24e54cd16d6966252eaef876b43e8e2'
         | 
| 4 | 
            +
              data.tar.gz: 59c16c569f2ea9a18d67f041b0a6bcd4b334d747a165e8801192094518a0a11b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 457122cce9314f5f6af45c73fc2b55977e98765d5aa13e18e6a7f6ea614f0af0559857a6a735c4c066760b62af9fa970200645fb93f1f4fd333a6f3412297ad5
         | 
| 7 | 
            +
              data.tar.gz: 4f503461cc54439ea891b4c0827d93a8e403abac1e9503f5be7b422c09abfae59917507d029ea0a3d6bb2cde10c64c256e9c6463ef0e1faace5e568d4d7d6282
         | 
    
        data/README.md
    CHANGED
    
    | @@ -2,10 +2,11 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            [](https://travis-ci.com/etscrivner/rbsecp256k1) [](https://badge.fury.io/rb/rbsecp256k1)
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
            and later libsecp256k1 is bundled with the gem.
         | 
| 5 | 
            +
            Native extension gem for secp256k1 ECDSA. Wraps [libsecp256k1](https://github.com/bitcoin-core/secp256k1). In
         | 
| 6 | 
            +
            rbsecp256k1 3.0.0 and later libsecp256k1 is bundled with the gem.
         | 
| 7 7 |  | 
| 8 | 
            -
            [Documentation](documentation/index.md)
         | 
| 8 | 
            +
            * [Documentation](documentation/index.md)
         | 
| 9 | 
            +
            * [Examples](examples/README.md)
         | 
| 9 10 |  | 
| 10 11 | 
             
            ### Why wrap libsecp256k1?
         | 
| 11 12 |  | 
| @@ -16,6 +17,9 @@ faster than the OpenSSL implementation of the same curve. It is the only library | |
| 16 17 | 
             
            that provides constant time signing of this curve and has been deployed as part
         | 
| 17 18 | 
             
            of Bitcoin since [v0.10.0](https://bitcoin.org/en/release/v0.10.0#improved-signing-security)
         | 
| 18 19 |  | 
| 20 | 
            +
            Natively wrapping the library in an extension gem means users don't have to
         | 
| 21 | 
            +
            worry about compiling or locating the library, unlike many [FFI](https://github.com/ffi/ffi) based gems.
         | 
| 22 | 
            +
             | 
| 19 23 | 
             
            ## Installation
         | 
| 20 24 |  | 
| 21 25 | 
             
            The simplest installation:
         | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/documentation/context.md
    CHANGED
    
    | @@ -10,10 +10,25 @@ for multiple operations as much as possible. | |
| 10 10 | 
             
            Initializers
         | 
| 11 11 | 
             
            ------------
         | 
| 12 12 |  | 
| 13 | 
            -
            #### new
         | 
| 13 | 
            +
            #### new(context_randomization_bytes: nil)
         | 
| 14 14 |  | 
| 15 15 | 
             
            Returns a newly initialized libsecp256k1 context. The context is randomized at
         | 
| 16 | 
            -
            initialization | 
| 16 | 
            +
            initialization if given `context_randomization_bytes`. The
         | 
| 17 | 
            +
            `context_randomization_bytes` argument can optionally take a string containing
         | 
| 18 | 
            +
            32 bytes of random data, if not provided then the Context is not randomized and
         | 
| 19 | 
            +
            may be vulnerable to side-channel attacks.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            Class Methods
         | 
| 22 | 
            +
            -------------
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            #### create
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            Creates and returns a new randomized `Context` using `SecureRandom` for the
         | 
| 27 | 
            +
            random initialization bytes. This is the recommended method for initialization.
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            #### create_unrandomized
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            Creates a new unrandomized `Context`.
         | 
| 17 32 |  | 
| 18 33 | 
             
            Instance Methods
         | 
| 19 34 | 
             
            ----------------
         | 
| @@ -23,7 +38,7 @@ Instance Methods | |
| 23 38 | 
             
            **Requires:** libsecp256k1 was built with the experimental ECDH module.
         | 
| 24 39 |  | 
| 25 40 | 
             
            Takes a `point` ([PublicKey](public_key.md)) and a `scalar` ([PrivateKey](private_key.md)) and returns a new
         | 
| 26 | 
            -
            [SharedSecret](shared_secret.md) containing the 32-byte shared secret. Raises a ` | 
| 41 | 
            +
            [SharedSecret](shared_secret.md) containing the 32-byte shared secret. Raises a `Secp256k1::Error` if
         | 
| 27 42 | 
             
            the `scalar` is invalid (zero or causes an overflow).
         | 
| 28 43 |  | 
| 29 44 | 
             
            #### generate_key_pair
         | 
| @@ -34,7 +49,7 @@ secure random number generator (CSRNG) provided by OpenSSL. | |
| 34 49 | 
             
            #### key_pair_from_private_key(private_key_data)
         | 
| 35 50 |  | 
| 36 51 | 
             
            Returns a new [KeyPair](key_pair.md) from the given `private_key_data`. The
         | 
| 37 | 
            -
            `private_key_data` is expected to be a binary string. Raises a ` | 
| 52 | 
            +
            `private_key_data` is expected to be a binary string. Raises a `Secp256k1::Error`
         | 
| 38 53 | 
             
            if the private key is invalid or key derivation fails.
         | 
| 39 54 |  | 
| 40 55 | 
             
            #### recoverable_signature_from_compact(compact_signature, recovery_id)
         | 
| @@ -42,7 +57,7 @@ if the private key is invalid or key derivation fails. | |
| 42 57 | 
             
            **Requires:** libsecp256k1 was build with recovery module.
         | 
| 43 58 |  | 
| 44 59 | 
             
            Attempts to load a [RecoverableSignature](recoverable_signature.md) from the given `compact_signature`
         | 
| 45 | 
            -
            and `recovery_id`. Raises a  | 
| 60 | 
            +
            and `recovery_id`. Raises a `Secp256k1::DeserializationError` if the signature data or recovery ID are invalid.
         | 
| 46 61 |  | 
| 47 62 | 
             
            #### sign(private_key, hash32)
         | 
| 48 63 |  | 
    
        data/documentation/index.md
    CHANGED
    
    | @@ -48,7 +48,7 @@ This example demonstrates how to create a new libsecp256k1 context. This is the | |
| 48 48 | 
             
            first step of using this library:
         | 
| 49 49 |  | 
| 50 50 | 
             
            ```ruby
         | 
| 51 | 
            -
            context = Secp256k1::Context. | 
| 51 | 
            +
            context = Secp256k1::Context.create
         | 
| 52 52 | 
             
            # => #<Secp256k1::Context:0x0000559b0bd8f5d0>
         | 
| 53 53 | 
             
            ```
         | 
| 54 54 |  | 
| @@ -57,7 +57,7 @@ context = Secp256k1::Context.new | |
| 57 57 | 
             
            This example shows how to generate a new public-private key pair:
         | 
| 58 58 |  | 
| 59 59 | 
             
            ```ruby
         | 
| 60 | 
            -
            context = Secp256k1::Context. | 
| 60 | 
            +
            context = Secp256k1::Context.create
         | 
| 61 61 | 
             
            key_pair = context.generate_key_pair
         | 
| 62 62 | 
             
            # => #<Secp256k1::KeyPair:0x0000559b0bc876b0 @public_key=#<Secp256k1::PublicKey:0x0000559b0bc876d8>, @private_key=#<Secp256k1::PrivateKey:0x0000559b0bc87700 @data="\r\xA7\xB3<\x92\xCDw\xC1\xDB\xEB[BB;=\x80\xB83\xA8]\x06\xD9\x90\xF8v\xFFi\xF0/\x1E\x96\xF9">>
         | 
| 63 63 | 
             
            ```
         | 
| @@ -67,7 +67,7 @@ key_pair = context.generate_key_pair | |
| 67 67 | 
             
            This example shows how to generate compressed and uncompressed public keys:
         | 
| 68 68 |  | 
| 69 69 | 
             
            ```ruby
         | 
| 70 | 
            -
            context = Secp256k1::Context. | 
| 70 | 
            +
            context = Secp256k1::Context.create
         | 
| 71 71 | 
             
            key_pair = context.generate_key_pair
         | 
| 72 72 |  | 
| 73 73 | 
             
            # 1. Get the binary representation of compressed public key
         | 
| @@ -94,7 +94,7 @@ This example shows how to sign a message using your private key: | |
| 94 94 | 
             
            ```ruby
         | 
| 95 95 | 
             
            require 'digest'
         | 
| 96 96 |  | 
| 97 | 
            -
            context = Secp256k1::Context. | 
| 97 | 
            +
            context = Secp256k1::Context.create
         | 
| 98 98 | 
             
            key_pair = context.generate_key_pair
         | 
| 99 99 |  | 
| 100 100 | 
             
            signature = context.sign(key_pair.private_key, Digest::SHA256.digest("test message"))
         | 
| @@ -109,7 +109,7 @@ representations of a signature: | |
| 109 109 | 
             
            ```ruby
         | 
| 110 110 | 
             
            require 'digest'
         | 
| 111 111 |  | 
| 112 | 
            -
            context = Secp256k1::Context. | 
| 112 | 
            +
            context = Secp256k1::Context.create
         | 
| 113 113 | 
             
            key_pair = context.generate_key_pair
         | 
| 114 114 |  | 
| 115 115 | 
             
            signature = context.sign(key_pair.private_key, Digest::SHA256.digest("test message"))
         | 
| @@ -138,7 +138,7 @@ This example shows how to verify a signature using a public key: | |
| 138 138 | 
             
            ```ruby
         | 
| 139 139 | 
             
            require 'digest'
         | 
| 140 140 |  | 
| 141 | 
            -
            context = Secp256k1::Context. | 
| 141 | 
            +
            context = Secp256k1::Context.create
         | 
| 142 142 | 
             
            key_pair = context.generate_key_pair
         | 
| 143 143 | 
             
            hash = Digest::SHA256.digest("test message")
         | 
| 144 144 |  | 
| @@ -158,7 +158,7 @@ context.verify(signature, key_pair.public_key, hash) | |
| 158 158 | 
             
            This example shows how to load a key pair from raw binary private key data:
         | 
| 159 159 |  | 
| 160 160 | 
             
            ```ruby
         | 
| 161 | 
            -
            context = Secp256k1::Context. | 
| 161 | 
            +
            context = Secp256k1::Context.create
         | 
| 162 162 |  | 
| 163 163 | 
             
            #1. Load private key alone
         | 
| 164 164 | 
             
            private_key = Secp256k1::PrivateKey.from_data("I\nX\x85\xAEz}\n\x9B\xA4\\\x81)\xD4\x9Aq\xFDH\t\xBE\x8EP\xC5.\xC6\x1F7-\x86\xA0\xCB\xF9")
         | 
| @@ -218,7 +218,7 @@ You can sign data producing a recoverable signature as follows: | |
| 218 218 | 
             
            require 'digest'
         | 
| 219 219 |  | 
| 220 220 | 
             
            hash = Digest::SHA256.digest('test message')
         | 
| 221 | 
            -
            context = Secp256k1::Context. | 
| 221 | 
            +
            context = Secp256k1::Context.create
         | 
| 222 222 | 
             
            key_pair = context.generate_key_pair
         | 
| 223 223 |  | 
| 224 224 | 
             
            signature = context.sign_recoverable(key_pair.private_key, hash)
         | 
| @@ -233,7 +233,7 @@ You can produce the compact binary serialization of a recoverable signature: | |
| 233 233 | 
             
            require 'digest'
         | 
| 234 234 |  | 
| 235 235 | 
             
            hash = Digest::SHA256.digest('test message')
         | 
| 236 | 
            -
            context = Secp256k1::Context. | 
| 236 | 
            +
            context = Secp256k1::Context.create
         | 
| 237 237 | 
             
            key_pair = context.generate_key_pair
         | 
| 238 238 |  | 
| 239 239 | 
             
            signature = context.sign_recoverable(key_pair.private_key, hash)
         | 
| @@ -247,7 +247,7 @@ You can load a recoverable signature give its compact representation and | |
| 247 247 | 
             
            recovery ID:
         | 
| 248 248 |  | 
| 249 249 | 
             
            ```ruby
         | 
| 250 | 
            -
            context = Secp256k1::Context. | 
| 250 | 
            +
            context = Secp256k1::Context.create
         | 
| 251 251 |  | 
| 252 252 | 
             
            compact_data = "D,\x9C\xA6%I\x14-\xCA\xC0\x11\x0F\xEB\x1E\xB0\xB6\\-\xE2\b\x98\xFB\xEA\xD5\x9BZ\xE6\xDF#\xC1\x1A\xEEL\xF02\xB1\xE9{\r\xEBhh<\\\xCF\xB6\x98\xEA\x8F\xF65\xF2\xBF\x84\xD8\xE5x\xF0\xA5)\xA2Wb\x9D"
         | 
| 253 253 | 
             
            recovery_id = 1
         | 
| @@ -265,7 +265,7 @@ for use by all methods that take a [Signature](signature.md) object: | |
| 265 265 | 
             
            require 'digest'
         | 
| 266 266 |  | 
| 267 267 | 
             
            hash = Digest::SHA256.digest('test message')
         | 
| 268 | 
            -
            context = Secp256k1::Context. | 
| 268 | 
            +
            context = Secp256k1::Context.create
         | 
| 269 269 | 
             
            key_pair = context.generate_key_pair
         | 
| 270 270 |  | 
| 271 271 | 
             
            recoverable_signature = context.sign_recoverable(key_pair.private_key, hash)
         | 
| @@ -281,7 +281,7 @@ You can recover the [PublicKey](public_key.md) associated with a recoverable sig | |
| 281 281 | 
             
            require 'digest'
         | 
| 282 282 |  | 
| 283 283 | 
             
            hash = Digest::SHA256.digest('test message')
         | 
| 284 | 
            -
            context = Secp256k1::Context. | 
| 284 | 
            +
            context = Secp256k1::Context.create
         | 
| 285 285 | 
             
            key_pair = context.generate_key_pair
         | 
| 286 286 |  | 
| 287 287 | 
             
            recoverable_signature = context.sign_recoverable(key_pair.private_key, hash)
         | 
| @@ -310,7 +310,7 @@ Secp256k1.have_ecdh? | |
| 310 310 | 
             
            To generate a shared secret run the following:
         | 
| 311 311 |  | 
| 312 312 | 
             
            ```ruby
         | 
| 313 | 
            -
            context = Secp256k1::Context. | 
| 313 | 
            +
            context = Secp256k1::Context.create
         | 
| 314 314 | 
             
            key_pair = context.generate_key_pair
         | 
| 315 315 |  | 
| 316 316 | 
             
            shared_secret = context.ecdh(key_pair.public_key, key_pair.private_key)
         | 
| @@ -11,7 +11,7 @@ Class Methods | |
| 11 11 | 
             
            #### from_data(private_key_data)
         | 
| 12 12 |  | 
| 13 13 | 
             
            Loads new private key from the given binary `private_key_data` string. Raises
         | 
| 14 | 
            -
            ` | 
| 14 | 
            +
            `Secp256k1::Error` if the given data is invalid.
         | 
| 15 15 |  | 
| 16 16 | 
             
            Instance Methods
         | 
| 17 17 | 
             
            ----------------
         | 
    
        data/documentation/public_key.md
    CHANGED
    
    | @@ -13,8 +13,8 @@ Class Methods | |
| 13 13 | 
             
            #### from_data(public_key_data)
         | 
| 14 14 |  | 
| 15 15 | 
             
            Parses compressed or uncompressed from binary string `public_key_data` and
         | 
| 16 | 
            -
            creates and returns a new public key from it. Raises a ` | 
| 17 | 
            -
            given public key data is invalid.
         | 
| 16 | 
            +
            creates and returns a new public key from it. Raises a `Secp256k1::DeserializationError`
         | 
| 17 | 
            +
            if the given public key data is invalid.
         | 
| 18 18 |  | 
| 19 19 | 
             
            Instance Methods
         | 
| 20 20 | 
             
            ----------------
         | 
    
        data/documentation/signature.md
    CHANGED
    
    | @@ -12,12 +12,12 @@ Class Methods | |
| 12 12 | 
             
            #### from_compact(compact_signature)
         | 
| 13 13 |  | 
| 14 14 | 
             
            Parses a signature from binary string `compact_signature`. Raises a
         | 
| 15 | 
            -
            ` | 
| 15 | 
            +
            `Secp256k1::DeserializationError` if the signature data is invalid.
         | 
| 16 16 |  | 
| 17 17 | 
             
            #### from_der_encoded(der_encoded_signature)
         | 
| 18 18 |  | 
| 19 19 | 
             
            Parses a signature from binary string `der_encoded_signature`. Raises a
         | 
| 20 | 
            -
            ` | 
| 20 | 
            +
            `Secp256k1::DeserializationError` if the signature data is invalid.
         | 
| 21 21 |  | 
| 22 22 | 
             
            Instance Methods
         | 
| 23 23 | 
             
            ----------------
         | 
    
        data/ext/rbsecp256k1/extconf.rb
    CHANGED
    
    | @@ -1,27 +1,16 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            require 'mini_portile2'
         | 
| 2 4 | 
             
            require 'mkmf'
         | 
| 3 5 | 
             
            require 'zip'
         | 
| 4 6 |  | 
| 5 | 
            -
            # Indicates the platform on which the package is being installed
         | 
| 6 | 
            -
            INSTALLING_OS =
         | 
| 7 | 
            -
              if RUBY_PLATFORM =~ /darwin/
         | 
| 8 | 
            -
                :macos
         | 
| 9 | 
            -
              elsif RUBY_PLATFORM =~ /linux/
         | 
| 10 | 
            -
                :linux
         | 
| 11 | 
            -
              else
         | 
| 12 | 
            -
                :unknown
         | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
            # Fixed path to Homebrew OpenSSL pkgconfig file
         | 
| 16 | 
            -
            HOMEBREW_OPENSSL_PKGCONFIG = '/usr/local/opt/openssl/lib/pkgconfig'.freeze
         | 
| 17 | 
            -
             | 
| 18 7 | 
             
            # Recipe for downloading and building libsecp256k1 as part of installation
         | 
| 19 8 | 
             
            class Secp256k1Recipe < MiniPortile
         | 
| 20 9 | 
             
              # Hard-coded URL for libsecp256k1 zipfile (HEAD of master as of 26-11-2018)
         | 
| 21 | 
            -
              LIBSECP256K1_ZIP_URL = 'https://github.com/bitcoin-core/secp256k1/archive/e34ceb333b1c0e6f4115ecbb80c632ac1042fa49.zip' | 
| 10 | 
            +
              LIBSECP256K1_ZIP_URL = 'https://github.com/bitcoin-core/secp256k1/archive/e34ceb333b1c0e6f4115ecbb80c632ac1042fa49.zip'
         | 
| 22 11 |  | 
| 23 12 | 
             
              # Expected SHA-256 of the zipfile above (computed using sha256sum)
         | 
| 24 | 
            -
              LIBSECP256K1_SHA256 = 'd87d3ca7ebc42edbabb0f38e79205040b24b09b3e6d1c9ac89585de9bf302143' | 
| 13 | 
            +
              LIBSECP256K1_SHA256 = 'd87d3ca7ebc42edbabb0f38e79205040b24b09b3e6d1c9ac89585de9bf302143'
         | 
| 25 14 |  | 
| 26 15 | 
             
              WITH_RECOVERY = ENV.fetch('WITH_RECOVERY', '1') == '1'
         | 
| 27 16 | 
             
              WITH_ECDH = ENV.fetch('WITH_ECDH', '1') == '1'
         | 
| @@ -82,46 +71,6 @@ class Secp256k1Recipe < MiniPortile | |
| 82 71 | 
             
              end
         | 
| 83 72 | 
             
            end
         | 
| 84 73 |  | 
| 85 | 
            -
            # OpenSSL flags
         | 
| 86 | 
            -
            message("checking for OpenSSL\n")
         | 
| 87 | 
            -
            results = pkg_config('openssl')
         | 
| 88 | 
            -
             | 
| 89 | 
            -
            # Failed to find package OpenSSL
         | 
| 90 | 
            -
            unless results && results[1]
         | 
| 91 | 
            -
              # Check if the user happens to have OpenSSL installed via Homebrew on a path
         | 
| 92 | 
            -
              # we know about.
         | 
| 93 | 
            -
              # rubocop:disable Style/GlobalVars
         | 
| 94 | 
            -
              if INSTALLING_OS == :macos && File.exist?(HOMEBREW_OPENSSL_PKGCONFIG)
         | 
| 95 | 
            -
                begin
         | 
| 96 | 
            -
                  require 'rubygems'
         | 
| 97 | 
            -
                  gem 'pkg-config', (gem_ver = '~> 1.3')
         | 
| 98 | 
            -
                  require 'pkg-config'
         | 
| 99 | 
            -
                rescue LoadError
         | 
| 100 | 
            -
                  message(
         | 
| 101 | 
            -
                    "pkg-config could not be used to find openssl\n" \
         | 
| 102 | 
            -
                    "Please install either `pkg-config` or the pkg-config gem via\n" \
         | 
| 103 | 
            -
                    "gem install pkg-config -v #{gem_ver.inspect}\n\n"
         | 
| 104 | 
            -
                  )
         | 
| 105 | 
            -
                else
         | 
| 106 | 
            -
                  message("Initial check failed. Trying homebrew openssl path...\n")
         | 
| 107 | 
            -
                  message("Using pkg-config gem version #{PKGConfig::VERSION}\n")
         | 
| 108 | 
            -
                  PKGConfig.add_path(HOMEBREW_OPENSSL_PKGCONFIG)
         | 
| 109 | 
            -
             | 
| 110 | 
            -
                  cflags = PKGConfig.cflags('openssl')
         | 
| 111 | 
            -
                  ldflags = PKGConfig.libs_only_L('openssl')
         | 
| 112 | 
            -
                  libs = PKGConfig.libs_only_l('openssl')
         | 
| 113 | 
            -
             | 
| 114 | 
            -
                  $CFLAGS += " " << cflags if cflags
         | 
| 115 | 
            -
                  $libs += " " << libs if libs
         | 
| 116 | 
            -
                  $LDFLAGS = [$LDFLAGS, ldflags].join(' ')
         | 
| 117 | 
            -
             | 
| 118 | 
            -
                  results = [cflags, libs, ldflags]
         | 
| 119 | 
            -
                end
         | 
| 120 | 
            -
              end
         | 
| 121 | 
            -
              # rubocop:enable Style/GlobalVars
         | 
| 122 | 
            -
            end
         | 
| 123 | 
            -
            abort "missing openssl pkg-config information" unless results && results[1]
         | 
| 124 | 
            -
             | 
| 125 74 | 
             
            if with_config('system-library')
         | 
| 126 75 | 
             
              # Require that libsecp256k1 be installed using `make install` or similar.
         | 
| 127 76 | 
             
              message("checking for libsecp256k1\n")
         | 
| @@ -142,6 +91,11 @@ else | |
| 142 91 | 
             
                  "-Wall"
         | 
| 143 92 | 
             
                ]
         | 
| 144 93 | 
             
              )
         | 
| 94 | 
            +
              append_ldflags(
         | 
| 95 | 
            +
                [
         | 
| 96 | 
            +
                  "-Wl,--no-as-needed"
         | 
| 97 | 
            +
                ]
         | 
| 98 | 
            +
              )
         | 
| 145 99 | 
             
              # rubocop:disable Style/GlobalVars
         | 
| 146 100 | 
             
              $LIBPATH = ["#{recipe.path}/lib"] | $LIBPATH
         | 
| 147 101 | 
             
              # rubocop:enable Style/GlobalVars
         | 
| @@ -6,12 +6,8 @@ | |
| 6 6 | 
             
            // and verifying signatures using the library.
         | 
| 7 7 | 
             
            //
         | 
| 8 8 | 
             
            // Dependencies:
         | 
| 9 | 
            -
            // | 
| 10 | 
            -
            // * openssl
         | 
| 9 | 
            +
            //   * libsecp256k1
         | 
| 11 10 | 
             
            #include <ruby.h>
         | 
| 12 | 
            -
             | 
| 13 | 
            -
            #include <openssl/rand.h>
         | 
| 14 | 
            -
             | 
| 15 11 | 
             
            #include <secp256k1.h>
         | 
| 16 12 |  | 
| 17 13 | 
             
            // Include recoverable signatures functionality if available
         | 
| @@ -44,6 +40,14 @@ | |
| 44 40 | 
             
            // applications. Context initialization is expensive so it is recommended that
         | 
| 45 41 | 
             
            // a single context be initialized and used throughout an application when
         | 
| 46 42 | 
             
            // possible.
         | 
| 43 | 
            +
            //
         | 
| 44 | 
            +
            // Exception Hierarchy:
         | 
| 45 | 
            +
            //
         | 
| 46 | 
            +
            // The following hierarchy is used for exceptions raised from the library:
         | 
| 47 | 
            +
            //
         | 
| 48 | 
            +
            // +- Error (Descends from StandardError)
         | 
| 49 | 
            +
            // |-- SerializationError
         | 
| 50 | 
            +
            // |-- DeserializationError
         | 
| 47 51 |  | 
| 48 52 | 
             
            //
         | 
| 49 53 | 
             
            // The section below contains purely internal methods used exclusively by the
         | 
| @@ -61,6 +65,9 @@ const size_t COMPACT_SIG_SIZE_BYTES = 64; | |
| 61 65 | 
             
            // objects from anywhere. The use of global variables seems to be inline with
         | 
| 62 66 | 
             
            // how the Ruby project builds its own extension gems.
         | 
| 63 67 | 
             
            static VALUE Secp256k1_module;
         | 
| 68 | 
            +
            static VALUE Secp256k1_Error_class;
         | 
| 69 | 
            +
            static VALUE Secp256k1_SerializationError_class;
         | 
| 70 | 
            +
            static VALUE Secp256k1_DeserializationError_class;
         | 
| 64 71 | 
             
            static VALUE Secp256k1_Context_class;
         | 
| 65 72 | 
             
            static VALUE Secp256k1_KeyPair_class;
         | 
| 66 73 | 
             
            static VALUE Secp256k1_PublicKey_class;
         | 
| @@ -262,33 +269,6 @@ typedef enum ResultT_dummy { | |
| 262 269 | 
             
              RESULT_FAILURE
         | 
| 263 270 | 
             
            } ResultT;
         | 
| 264 271 |  | 
| 265 | 
            -
            /**
         | 
| 266 | 
            -
             * Generate a series of cryptographically secure random bytes using OpenSSL.
         | 
| 267 | 
            -
             *
         | 
| 268 | 
            -
             * \param out_bytes Desired number of bytes will be written here.
         | 
| 269 | 
            -
             * \param in_size Number of bytes of random data to be generated.
         | 
| 270 | 
            -
             * \return RESULT_SUCCESS if the bytes were generated successfully,
         | 
| 271 | 
            -
             *   RESULT_FAILURE otherwise.
         | 
| 272 | 
            -
             */
         | 
| 273 | 
            -
            static ResultT
         | 
| 274 | 
            -
            GenerateRandomBytes(unsigned char *out_bytes, int in_size)
         | 
| 275 | 
            -
            {
         | 
| 276 | 
            -
              // OpenSSL RNG has not been seeded with enough data and is therefore
         | 
| 277 | 
            -
              // not usable.
         | 
| 278 | 
            -
              if (RAND_status() == 0)
         | 
| 279 | 
            -
              {
         | 
| 280 | 
            -
                return RESULT_FAILURE;
         | 
| 281 | 
            -
              }
         | 
| 282 | 
            -
             | 
| 283 | 
            -
              // Attempt to generate random bytes using the OpenSSL RNG
         | 
| 284 | 
            -
              if (RAND_bytes(out_bytes, in_size) != 1)
         | 
| 285 | 
            -
              {
         | 
| 286 | 
            -
                return RESULT_FAILURE;
         | 
| 287 | 
            -
              }
         | 
| 288 | 
            -
             | 
| 289 | 
            -
              return RESULT_SUCCESS;
         | 
| 290 | 
            -
            }
         | 
| 291 | 
            -
             | 
| 292 272 | 
             
            /**
         | 
| 293 273 | 
             
             * Computes the ECDSA signature of the given 32-byte SHA-256 hash.
         | 
| 294 274 | 
             
             *
         | 
| @@ -462,7 +442,7 @@ PublicKey_create_from_private_key(Context *in_context, | |
| 462 442 | 
             
                    (&public_key->pubkey),
         | 
| 463 443 | 
             
                    private_key_data) != 1)
         | 
| 464 444 | 
             
              {
         | 
| 465 | 
            -
                rb_raise( | 
| 445 | 
            +
                rb_raise(Secp256k1_DeserializationError_class, "invalid private key data");
         | 
| 466 446 | 
             
              }
         | 
| 467 447 |  | 
| 468 448 | 
             
              return result;
         | 
| @@ -483,7 +463,7 @@ PublicKey_create_from_data(unsigned char *in_public_key_data, | |
| 483 463 | 
             
                                            in_public_key_data,
         | 
| 484 464 | 
             
                                            in_public_key_data_len) != 1)
         | 
| 485 465 | 
             
              {
         | 
| 486 | 
            -
                rb_raise( | 
| 466 | 
            +
                rb_raise(Secp256k1_DeserializationError_class, "invalid public key data");
         | 
| 487 467 | 
             
              }
         | 
| 488 468 |  | 
| 489 469 | 
             
              return result;
         | 
| @@ -495,7 +475,7 @@ PublicKey_create_from_data(unsigned char *in_public_key_data, | |
| 495 475 | 
             
             * @param in_public_key_data [String] binary string with compressed or
         | 
| 496 476 | 
             
             *   uncompressed public key data.
         | 
| 497 477 | 
             
             * @return [Secp256k1::PublicKey] public key derived from data.
         | 
| 498 | 
            -
             * @raise [ | 
| 478 | 
            +
             * @raise [Secp256k1::DeserializationError] if public key data is invalid.
         | 
| 499 479 | 
             
             */
         | 
| 500 480 | 
             
            static VALUE
         | 
| 501 481 | 
             
            PublicKey_from_data(VALUE klass, VALUE in_public_key_data)
         | 
| @@ -631,7 +611,7 @@ PrivateKey_create(unsigned char *in_private_key_data) | |
| 631 611 | 
             
              if (secp256k1_ec_seckey_verify(secp256k1_context_no_precomp,
         | 
| 632 612 | 
             
                                             in_private_key_data) != 1)
         | 
| 633 613 | 
             
              {
         | 
| 634 | 
            -
                rb_raise( | 
| 614 | 
            +
                rb_raise(Secp256k1_Error_class, "invalid private key data");
         | 
| 635 615 | 
             
              }
         | 
| 636 616 |  | 
| 637 617 | 
             
              result = PrivateKey_alloc(Secp256k1_PrivateKey_class);
         | 
| @@ -649,7 +629,7 @@ PrivateKey_create(unsigned char *in_private_key_data) | |
| 649 629 | 
             
             * @param in_private_key_data [String] 32 byte binary string of private key
         | 
| 650 630 | 
             
             *   data.
         | 
| 651 631 | 
             
             * @return [Secp256k1::PrivateKey] private key loaded from the given data.
         | 
| 652 | 
            -
             * @raise [ | 
| 632 | 
            +
             * @raise [Secp256k1::Error] if private key data is not 32 bytes or is invalid.
         | 
| 653 633 | 
             
             */
         | 
| 654 634 | 
             
            static VALUE
         | 
| 655 635 | 
             
            PrivateKey_from_data(VALUE klass, VALUE in_private_key_data)
         | 
| @@ -659,7 +639,10 @@ PrivateKey_from_data(VALUE klass, VALUE in_private_key_data) | |
| 659 639 | 
             
              Check_Type(in_private_key_data, T_STRING);
         | 
| 660 640 | 
             
              if (RSTRING_LEN(in_private_key_data) != 32)
         | 
| 661 641 | 
             
              {
         | 
| 662 | 
            -
                rb_raise( | 
| 642 | 
            +
                rb_raise(
         | 
| 643 | 
            +
                  Secp256k1_Error_class,
         | 
| 644 | 
            +
                  "private key data must be 32 bytes in length"
         | 
| 645 | 
            +
                );
         | 
| 663 646 | 
             
              }
         | 
| 664 647 |  | 
| 665 648 | 
             
              private_key_data = (unsigned char*)StringValuePtr(in_private_key_data);
         | 
| @@ -714,7 +697,7 @@ Signature_alloc(VALUE klass) | |
| 714 697 | 
             
             * @param in_compact_signature [String] compact signature as 64-byte binary
         | 
| 715 698 | 
             
             *   string.
         | 
| 716 699 | 
             
             * @return [Secp256k1::Signature] object deserialized from compact signature.
         | 
| 717 | 
            -
             * @raise [ | 
| 700 | 
            +
             * @raise [Secp256k1::DeserializationError] if signature data is invalid.
         | 
| 718 701 | 
             
             */
         | 
| 719 702 | 
             
            static VALUE
         | 
| 720 703 | 
             
            Signature_from_compact(VALUE klass, VALUE in_compact_signature)
         | 
| @@ -727,7 +710,7 @@ Signature_from_compact(VALUE klass, VALUE in_compact_signature) | |
| 727 710 |  | 
| 728 711 | 
             
              if (RSTRING_LEN(in_compact_signature) != 64)
         | 
| 729 712 | 
             
              {
         | 
| 730 | 
            -
                rb_raise( | 
| 713 | 
            +
                rb_raise(Secp256k1_Error_class, "compact signature must be 64 bytes");
         | 
| 731 714 | 
             
              }
         | 
| 732 715 |  | 
| 733 716 | 
             
              signature_data = (unsigned char*)StringValuePtr(in_compact_signature);
         | 
| @@ -739,7 +722,7 @@ Signature_from_compact(VALUE klass, VALUE in_compact_signature) | |
| 739 722 | 
             
                                                          &(signature->sig),
         | 
| 740 723 | 
             
                                                          signature_data) != 1)
         | 
| 741 724 | 
             
              {
         | 
| 742 | 
            -
                rb_raise( | 
| 725 | 
            +
                rb_raise(Secp256k1_DeserializationError_class, "invalid compact signature");
         | 
| 743 726 | 
             
              }
         | 
| 744 727 |  | 
| 745 728 | 
             
              return signature_result;
         | 
| @@ -752,7 +735,7 @@ Signature_from_compact(VALUE klass, VALUE in_compact_signature) | |
| 752 735 | 
             
             *   string.
         | 
| 753 736 | 
             
             * @return [Secp256k1::Signature] signature object initialized using signature
         | 
| 754 737 | 
             
             *   data.
         | 
| 755 | 
            -
             * @raise [ | 
| 738 | 
            +
             * @raise [Secp256k1::DeserializationError] if signature data is invalid.
         | 
| 756 739 | 
             
             */
         | 
| 757 740 | 
             
            static VALUE
         | 
| 758 741 | 
             
            Signature_from_der_encoded(VALUE klass, VALUE in_der_encoded_signature)
         | 
| @@ -773,7 +756,7 @@ Signature_from_der_encoded(VALUE klass, VALUE in_der_encoded_signature) | |
| 773 756 | 
             
                                                      signature_data,
         | 
| 774 757 | 
             
                                                      RSTRING_LEN(in_der_encoded_signature)) != 1)
         | 
| 775 758 | 
             
              {
         | 
| 776 | 
            -
                rb_raise( | 
| 759 | 
            +
                rb_raise(Secp256k1_DeserializationError_class, "invalid DER encoded signature");
         | 
| 777 760 | 
             
              }
         | 
| 778 761 |  | 
| 779 762 | 
             
              return signature_result;
         | 
| @@ -800,7 +783,10 @@ Signature_der_encoded(VALUE self) | |
| 800 783 | 
             
                                                          &der_signature_len,
         | 
| 801 784 | 
             
                                                          &(signature->sig)) != 1)
         | 
| 802 785 | 
             
              {
         | 
| 803 | 
            -
                rb_raise( | 
| 786 | 
            +
                rb_raise(
         | 
| 787 | 
            +
                  Secp256k1_SerializationError_class,
         | 
| 788 | 
            +
                  "could not compute DER encoded signature"
         | 
| 789 | 
            +
                );
         | 
| 804 790 | 
             
              }
         | 
| 805 791 |  | 
| 806 792 | 
             
              return rb_str_new((char*)der_signature, der_signature_len);
         | 
| @@ -824,7 +810,10 @@ Signature_compact(VALUE self) | |
| 824 810 | 
             
                                                              compact_signature,
         | 
| 825 811 | 
             
                                                              &(signature->sig)) != 1)
         | 
| 826 812 | 
             
              {
         | 
| 827 | 
            -
                rb_raise( | 
| 813 | 
            +
                rb_raise(
         | 
| 814 | 
            +
                  Secp256k1_SerializationError_class,
         | 
| 815 | 
            +
                  "unable to compute compact signature"
         | 
| 816 | 
            +
                );
         | 
| 828 817 | 
             
              }
         | 
| 829 818 |  | 
| 830 819 | 
             
              return rb_str_new((char*)compact_signature, COMPACT_SIG_SIZE_BYTES);
         | 
| @@ -932,7 +921,7 @@ RecoverableSignature_alloc(VALUE klass) | |
| 932 921 | 
             
             *
         | 
| 933 922 | 
             
             * @return [Array] first element is the 64 byte compact encoding of signature,
         | 
| 934 923 | 
             
             *   the second element is the integer recovery ID.
         | 
| 935 | 
            -
             * @raise [ | 
| 924 | 
            +
             * @raise [Secp256k1::SerializationError] if signature serialization fails.
         | 
| 936 925 | 
             
             */
         | 
| 937 926 | 
             
            static VALUE
         | 
| 938 927 | 
             
            RecoverableSignature_compact(VALUE self)
         | 
| @@ -955,7 +944,10 @@ RecoverableSignature_compact(VALUE self) | |
| 955 944 | 
             
                    &recovery_id,
         | 
| 956 945 | 
             
                    &(recoverable_signature->sig)) != 1)
         | 
| 957 946 | 
             
              {
         | 
| 958 | 
            -
                rb_raise( | 
| 947 | 
            +
                rb_raise(
         | 
| 948 | 
            +
                  Secp256k1_SerializationError_class,
         | 
| 949 | 
            +
                  "unable to serialize recoverable signature"
         | 
| 950 | 
            +
                );
         | 
| 959 951 | 
             
              }
         | 
| 960 952 |  | 
| 961 953 | 
             
              // Create a new array with room for 2 elements and push data onto it
         | 
| @@ -1008,7 +1000,9 @@ RecoverableSignature_to_signature(VALUE self) | |
| 1008 1000 | 
             
             *
         | 
| 1009 1001 | 
             
             * @param in_hash32 [String] 32-byte SHA-256 hash of data.
         | 
| 1010 1002 | 
             
             * @return [Secp256k1::PublicKey] recovered public key.
         | 
| 1011 | 
            -
             * @raise [ | 
| 1003 | 
            +
             * @raise [Secp256k1::Error] if hash given is not 32 bytes.
         | 
| 1004 | 
            +
             * @raise [Secp256k1::DeserializationError] if public key could not be
         | 
| 1005 | 
            +
             *   recovered.
         | 
| 1012 1006 | 
             
             */
         | 
| 1013 1007 | 
             
            static VALUE
         | 
| 1014 1008 | 
             
            RecoverableSignature_recover_public_key(VALUE self, VALUE in_hash32)
         | 
| @@ -1021,7 +1015,7 @@ RecoverableSignature_recover_public_key(VALUE self, VALUE in_hash32) | |
| 1021 1015 | 
             
              Check_Type(in_hash32, T_STRING);
         | 
| 1022 1016 | 
             
              if (RSTRING_LEN(in_hash32) != 32)
         | 
| 1023 1017 | 
             
              {
         | 
| 1024 | 
            -
                rb_raise( | 
| 1018 | 
            +
                rb_raise(Secp256k1_Error_class, "in_hash32 is not 32 bytes in length");
         | 
| 1025 1019 | 
             
              }
         | 
| 1026 1020 |  | 
| 1027 1021 | 
             
              TypedData_Get_Struct(
         | 
| @@ -1043,7 +1037,7 @@ RecoverableSignature_recover_public_key(VALUE self, VALUE in_hash32) | |
| 1043 1037 | 
             
                return result;
         | 
| 1044 1038 | 
             
              }
         | 
| 1045 1039 |  | 
| 1046 | 
            -
              rb_raise( | 
| 1040 | 
            +
              rb_raise(Secp256k1_DeserializationError_class, "unable to recover public key");
         | 
| 1047 1041 | 
             
            }
         | 
| 1048 1042 |  | 
| 1049 1043 | 
             
            /**
         | 
| @@ -1131,14 +1125,27 @@ Context_alloc(VALUE klass) | |
| 1131 1125 | 
             
             *
         | 
| 1132 1126 | 
             
             * Context initialization should be infrequent as it is an expensive operation.
         | 
| 1133 1127 | 
             
             *
         | 
| 1128 | 
            +
             * @param context_randomization_bytes [String,nil] (Optional) 32 bytes of
         | 
| 1129 | 
            +
             *   random data used to randomize the context. If omitted then the
         | 
| 1130 | 
            +
             *   context remains unrandomized. It is recommended that you provide this
         | 
| 1131 | 
            +
             *   argument.
         | 
| 1134 1132 | 
             
             * @return [Secp256k1::Context] 
         | 
| 1135 | 
            -
             * @raise [ | 
| 1133 | 
            +
             * @raise [Secp256k1::Error] if context randomization fails.
         | 
| 1136 1134 | 
             
             */
         | 
| 1137 1135 | 
             
            static VALUE
         | 
| 1138 | 
            -
            Context_initialize(VALUE self)
         | 
| 1136 | 
            +
            Context_initialize(int argc, const VALUE* argv, VALUE self)
         | 
| 1139 1137 | 
             
            {
         | 
| 1140 1138 | 
             
              Context *context;
         | 
| 1141 | 
            -
              unsigned char  | 
| 1139 | 
            +
              unsigned char *seed32;
         | 
| 1140 | 
            +
              VALUE context_randomization_bytes;
         | 
| 1141 | 
            +
              VALUE opts;
         | 
| 1142 | 
            +
              static ID kwarg_ids;
         | 
| 1143 | 
            +
             | 
| 1144 | 
            +
              context_randomization_bytes = Qnil;
         | 
| 1145 | 
            +
              if (!kwarg_ids)
         | 
| 1146 | 
            +
              {
         | 
| 1147 | 
            +
                CONST_ID(kwarg_ids, "context_randomization_bytes");
         | 
| 1148 | 
            +
              }
         | 
| 1142 1149 |  | 
| 1143 1150 | 
             
              TypedData_Get_Struct(self, Context, &Context_DataType, context);
         | 
| 1144 1151 |  | 
| @@ -1146,50 +1153,46 @@ Context_initialize(VALUE self) | |
| 1146 1153 | 
             
                SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY
         | 
| 1147 1154 | 
             
              );
         | 
| 1148 1155 |  | 
| 1149 | 
            -
              //  | 
| 1150 | 
            -
              //  | 
| 1151 | 
            -
               | 
| 1152 | 
            -
               | 
| 1156 | 
            +
              // Handle optional second argument containing random bytes to use for
         | 
| 1157 | 
            +
              // randomization. We pass ":" to rb_scan_args to say that we expect keyword
         | 
| 1158 | 
            +
              // arguments. We then parse the opts result of the scan in order to grab
         | 
| 1159 | 
            +
              // context_randomization_bytes from the hash.
         | 
| 1160 | 
            +
              rb_scan_args(argc, argv, ":", &opts);
         | 
| 1161 | 
            +
              rb_get_kwargs(opts, &kwarg_ids, 0, 1, &context_randomization_bytes);
         | 
| 1162 | 
            +
             | 
| 1163 | 
            +
              // We need this check because rb_get_kwargs will set the result to Qundef if
         | 
| 1164 | 
            +
              // the keyword argument is not provided. This lets us use the NIL_P
         | 
| 1165 | 
            +
              // predicate.
         | 
| 1166 | 
            +
              if (context_randomization_bytes == Qundef)
         | 
| 1153 1167 | 
             
              {
         | 
| 1154 | 
            -
                 | 
| 1168 | 
            +
                context_randomization_bytes = Qnil;
         | 
| 1155 1169 | 
             
              }
         | 
| 1156 1170 |  | 
| 1157 | 
            -
               | 
| 1158 | 
            -
            }
         | 
| 1159 | 
            -
             | 
| 1160 | 
            -
            /**
         | 
| 1161 | 
            -
             * Generate a new public-private key pair.
         | 
| 1162 | 
            -
             *
         | 
| 1163 | 
            -
             * @return [Secp256k1::KeyPair] newly generated key pair.
         | 
| 1164 | 
            -
             * @raise [RuntimeError] if private key generation fails.
         | 
| 1165 | 
            -
             */
         | 
| 1166 | 
            -
            static VALUE
         | 
| 1167 | 
            -
            Context_generate_key_pair(VALUE self)
         | 
| 1168 | 
            -
            {
         | 
| 1169 | 
            -
              Context *context;
         | 
| 1170 | 
            -
              VALUE private_key;
         | 
| 1171 | 
            -
              VALUE public_key;
         | 
| 1172 | 
            -
              VALUE result;
         | 
| 1173 | 
            -
              unsigned char private_key_bytes[32];
         | 
| 1174 | 
            -
             | 
| 1175 | 
            -
              if (FAILURE(GenerateRandomBytes(private_key_bytes, 32)))
         | 
| 1171 | 
            +
              if (!NIL_P(context_randomization_bytes)) // Random bytes given
         | 
| 1176 1172 | 
             
              {
         | 
| 1177 | 
            -
                 | 
| 1173 | 
            +
                Check_Type(context_randomization_bytes, T_STRING);
         | 
| 1174 | 
            +
                if (RSTRING_LEN(context_randomization_bytes) != 32)
         | 
| 1175 | 
            +
                {
         | 
| 1176 | 
            +
                  rb_raise(
         | 
| 1177 | 
            +
                    Secp256k1_Error_class,
         | 
| 1178 | 
            +
                    "context_randomization_bytes must be 32 bytes in length"
         | 
| 1179 | 
            +
                  );
         | 
| 1180 | 
            +
                }
         | 
| 1181 | 
            +
             | 
| 1182 | 
            +
                seed32 = (unsigned char*)StringValuePtr(context_randomization_bytes);
         | 
| 1183 | 
            +
             | 
| 1184 | 
            +
                // Randomize the context at initialization time rather than before calls so
         | 
| 1185 | 
            +
                // the same context can be used across threads safely.
         | 
| 1186 | 
            +
                if (secp256k1_context_randomize(context->ctx, seed32) != 1)
         | 
| 1187 | 
            +
                {
         | 
| 1188 | 
            +
                  rb_raise(
         | 
| 1189 | 
            +
                    Secp256k1_Error_class,
         | 
| 1190 | 
            +
                    "context randomization failed"
         | 
| 1191 | 
            +
                  );
         | 
| 1192 | 
            +
                }
         | 
| 1178 1193 | 
             
              }
         | 
| 1179 1194 |  | 
| 1180 | 
            -
               | 
| 1181 | 
            -
             | 
| 1182 | 
            -
              private_key = PrivateKey_create(private_key_bytes);
         | 
| 1183 | 
            -
              public_key = PublicKey_create_from_private_key(context, private_key_bytes);
         | 
| 1184 | 
            -
              result = rb_funcall(
         | 
| 1185 | 
            -
                Secp256k1_KeyPair_class,
         | 
| 1186 | 
            -
                rb_intern("new"),
         | 
| 1187 | 
            -
                2,
         | 
| 1188 | 
            -
                public_key,
         | 
| 1189 | 
            -
                private_key
         | 
| 1190 | 
            -
              );
         | 
| 1191 | 
            -
             | 
| 1192 | 
            -
              return result;
         | 
| 1195 | 
            +
              return self;
         | 
| 1193 1196 | 
             
            }
         | 
| 1194 1197 |  | 
| 1195 1198 | 
             
            /**
         | 
| @@ -1197,7 +1200,7 @@ Context_generate_key_pair(VALUE self) | |
| 1197 1200 | 
             
             *
         | 
| 1198 1201 | 
             
             * @param in_private_key_data [String] binary private key data
         | 
| 1199 1202 | 
             
             * @return [Secp256k1::KeyPair] key pair initialized from the private key data.
         | 
| 1200 | 
            -
             * @raise [ | 
| 1203 | 
            +
             * @raise [Secp256k1::Error] if the private key data is invalid or key derivation
         | 
| 1201 1204 | 
             
             *   fails.
         | 
| 1202 1205 | 
             
             */
         | 
| 1203 1206 | 
             
            static VALUE
         | 
| @@ -1213,7 +1216,7 @@ Context_key_pair_from_private_key(VALUE self, VALUE in_private_key_data) | |
| 1213 1216 |  | 
| 1214 1217 | 
             
              if (RSTRING_LEN(in_private_key_data) != 32)
         | 
| 1215 1218 | 
             
              {
         | 
| 1216 | 
            -
                rb_raise( | 
| 1219 | 
            +
                rb_raise(Secp256k1_Error_class, "private key data must be 32 bytes in length");
         | 
| 1217 1220 | 
             
              }
         | 
| 1218 1221 |  | 
| 1219 1222 | 
             
              private_key_data = (unsigned char*)StringValuePtr(in_private_key_data);
         | 
| @@ -1237,8 +1240,8 @@ Context_key_pair_from_private_key(VALUE self, VALUE in_private_key_data) | |
| 1237 1240 | 
             
             *   signing.
         | 
| 1238 1241 | 
             
             * @param in_hash32 [String] 32-byte binary string with SHA-256 hash of data.
         | 
| 1239 1242 | 
             
             * @return [Secp256k1::Signature] signature resulting from signing data.
         | 
| 1240 | 
            -
             * @raise [ | 
| 1241 | 
            -
             *  | 
| 1243 | 
            +
             * @raise [Secp256k1::Error] if hash is not 32-bytes in length or signature
         | 
| 1244 | 
            +
             *   computation fails.
         | 
| 1242 1245 | 
             
             */
         | 
| 1243 1246 | 
             
            static VALUE
         | 
| 1244 1247 | 
             
            Context_sign(VALUE self, VALUE in_private_key, VALUE in_hash32)
         | 
| @@ -1253,7 +1256,7 @@ Context_sign(VALUE self, VALUE in_private_key, VALUE in_hash32) | |
| 1253 1256 |  | 
| 1254 1257 | 
             
              if (RSTRING_LEN(in_hash32) != 32)
         | 
| 1255 1258 | 
             
              {
         | 
| 1256 | 
            -
                rb_raise( | 
| 1259 | 
            +
                rb_raise(Secp256k1_Error_class, "in_hash32 is not 32 bytes in length");
         | 
| 1257 1260 | 
             
              }
         | 
| 1258 1261 |  | 
| 1259 1262 | 
             
              TypedData_Get_Struct(self, Context, &Context_DataType, context);
         | 
| @@ -1272,7 +1275,7 @@ Context_sign(VALUE self, VALUE in_private_key, VALUE in_hash32) | |
| 1272 1275 | 
             
                return signature_result;
         | 
| 1273 1276 | 
             
              }
         | 
| 1274 1277 |  | 
| 1275 | 
            -
              rb_raise( | 
| 1278 | 
            +
              rb_raise(Secp256k1_Error_class, "unable to compute signature");
         | 
| 1276 1279 | 
             
            }
         | 
| 1277 1280 |  | 
| 1278 1281 | 
             
            /**
         | 
| @@ -1284,7 +1287,7 @@ Context_sign(VALUE self, VALUE in_private_key, VALUE in_hash32) | |
| 1284 1287 | 
             
             * @param in_hash32 [String] 32-byte binary string containing SHA-256 hash of
         | 
| 1285 1288 | 
             
             *   data.
         | 
| 1286 1289 | 
             
             * @return [Boolean] True if the signature is valid, false otherwise.
         | 
| 1287 | 
            -
             * @raise [ | 
| 1290 | 
            +
             * @raise [Secp256k1::Error] if hash is not 32-bytes in length.
         | 
| 1288 1291 | 
             
             */
         | 
| 1289 1292 | 
             
            static VALUE
         | 
| 1290 1293 | 
             
            Context_verify(VALUE self, VALUE in_signature, VALUE in_pubkey, VALUE in_hash32)
         | 
| @@ -1298,7 +1301,7 @@ Context_verify(VALUE self, VALUE in_signature, VALUE in_pubkey, VALUE in_hash32) | |
| 1298 1301 |  | 
| 1299 1302 | 
             
              if (RSTRING_LEN(in_hash32) != 32)
         | 
| 1300 1303 | 
             
              {
         | 
| 1301 | 
            -
                rb_raise( | 
| 1304 | 
            +
                rb_raise(Secp256k1_Error_class, "in_hash32 is not 32-bytes in length");
         | 
| 1302 1305 | 
             
              }
         | 
| 1303 1306 |  | 
| 1304 1307 | 
             
              TypedData_Get_Struct(self, Context, &Context_DataType, context);
         | 
| @@ -1328,7 +1331,8 @@ Context_verify(VALUE self, VALUE in_signature, VALUE in_pubkey, VALUE in_hash32) | |
| 1328 1331 | 
             
             * @param in_hash32 [String] 32-byte binary string with SHA-256 hash of data.
         | 
| 1329 1332 | 
             
             * @return [Secp256k1::RecoverableSignature] recoverable signature produced by
         | 
| 1330 1333 | 
             
             *   signing the SHA-256 hash `in_hash32` with `in_private_key`.
         | 
| 1331 | 
            -
             * @raise [ | 
| 1334 | 
            +
             * @raise [Secp256k1::Error] if the hash is not 32 bytes or signature could not
         | 
| 1335 | 
            +
             *   be computed.
         | 
| 1332 1336 | 
             
             */
         | 
| 1333 1337 | 
             
            static VALUE
         | 
| 1334 1338 | 
             
            Context_sign_recoverable(VALUE self, VALUE in_private_key, VALUE in_hash32)
         | 
| @@ -1342,7 +1346,7 @@ Context_sign_recoverable(VALUE self, VALUE in_private_key, VALUE in_hash32) | |
| 1342 1346 | 
             
              Check_Type(in_hash32, T_STRING);
         | 
| 1343 1347 | 
             
              if (RSTRING_LEN(in_hash32) != 32)
         | 
| 1344 1348 | 
             
              {
         | 
| 1345 | 
            -
                rb_raise( | 
| 1349 | 
            +
                rb_raise(Secp256k1_Error_class, "in_hash32 is not 32 bytes in length");
         | 
| 1346 1350 | 
             
              }
         | 
| 1347 1351 |  | 
| 1348 1352 | 
             
              TypedData_Get_Struct(self, Context, &Context_DataType, context);
         | 
| @@ -1368,7 +1372,7 @@ Context_sign_recoverable(VALUE self, VALUE in_private_key, VALUE in_hash32) | |
| 1368 1372 | 
             
                return result;
         | 
| 1369 1373 | 
             
              }
         | 
| 1370 1374 |  | 
| 1371 | 
            -
              rb_raise( | 
| 1375 | 
            +
              rb_raise(Secp256k1_Error_class, "unable to compute recoverable signature");
         | 
| 1372 1376 | 
             
            }
         | 
| 1373 1377 |  | 
| 1374 1378 | 
             
            /**
         | 
| @@ -1378,8 +1382,9 @@ Context_sign_recoverable(VALUE self, VALUE in_private_key, VALUE in_hash32) | |
| 1378 1382 | 
             
             *   data.
         | 
| 1379 1383 | 
             
             * @param in_recovery_id [Integer] recovery ID (range [0, 3])
         | 
| 1380 1384 | 
             
             * @return [Secp256k1::RecoverableSignature] signature parsed from data.
         | 
| 1381 | 
            -
             * @raise [ | 
| 1382 | 
            -
             * | 
| 1385 | 
            +
             * @raise [Secp256k1::DeserializationError] if signature data or recovery ID is
         | 
| 1386 | 
            +
             *   invalid.
         | 
| 1387 | 
            +
             * @raise [Secp256k1::Error] if compact signature is not 64 bytes or recovery ID
         | 
| 1383 1388 | 
             
             *   is not in range [0, 3].
         | 
| 1384 1389 | 
             
             */
         | 
| 1385 1390 | 
             
            static VALUE
         | 
| @@ -1401,12 +1406,12 @@ Context_recoverable_signature_from_compact( | |
| 1401 1406 |  | 
| 1402 1407 | 
             
              if (RSTRING_LEN(in_compact_sig) != 64)
         | 
| 1403 1408 | 
             
              {
         | 
| 1404 | 
            -
                rb_raise( | 
| 1409 | 
            +
                rb_raise(Secp256k1_Error_class, "compact signature is not 64 bytes");
         | 
| 1405 1410 | 
             
              }
         | 
| 1406 1411 |  | 
| 1407 1412 | 
             
              if (recovery_id < 0 || recovery_id > 3)
         | 
| 1408 1413 | 
             
              {
         | 
| 1409 | 
            -
                rb_raise( | 
| 1414 | 
            +
                rb_raise(Secp256k1_Error_class, "invalid recovery ID, must be in range [0, 3]");
         | 
| 1410 1415 | 
             
              }
         | 
| 1411 1416 |  | 
| 1412 1417 | 
             
              result = RecoverableSignature_alloc(Secp256k1_RecoverableSignature_class);
         | 
| @@ -1427,7 +1432,7 @@ Context_recoverable_signature_from_compact( | |
| 1427 1432 | 
             
                return result;
         | 
| 1428 1433 | 
             
              }
         | 
| 1429 1434 |  | 
| 1430 | 
            -
              rb_raise( | 
| 1435 | 
            +
              rb_raise(Secp256k1_DeserializationError_class, "unable to parse recoverable signature");
         | 
| 1431 1436 | 
             
            }
         | 
| 1432 1437 |  | 
| 1433 1438 | 
             
            #endif // HAVE_SECP256K1_RECOVERY_H
         | 
| @@ -1443,7 +1448,7 @@ Context_recoverable_signature_from_compact( | |
| 1443 1448 | 
             
             * @param point [Secp256k1::PublicKey] public-key representing ECDH point.
         | 
| 1444 1449 | 
             
             * @param scalar [Secp256k1::PrivateKey] private-key representing ECDH scalar.
         | 
| 1445 1450 | 
             
             * @return [Secp256k1::SharedSecret] shared secret
         | 
| 1446 | 
            -
             * @raise [ | 
| 1451 | 
            +
             * @raise [Secp256k1::Error] If scalar was invalid (zero or caused overflow).
         | 
| 1447 1452 | 
             
             */
         | 
| 1448 1453 | 
             
            static VALUE
         | 
| 1449 1454 | 
             
            Context_ecdh(VALUE self, VALUE point, VALUE scalar)
         | 
| @@ -1470,7 +1475,7 @@ Context_ecdh(VALUE self, VALUE point, VALUE scalar) | |
| 1470 1475 | 
             
                                 NULL,
         | 
| 1471 1476 | 
             
                                 NULL) != 1)
         | 
| 1472 1477 | 
             
              {
         | 
| 1473 | 
            -
                rb_raise( | 
| 1478 | 
            +
                rb_raise(Secp256k1_Error_class, "invalid scalar provided to ecdh");
         | 
| 1474 1479 | 
             
              }
         | 
| 1475 1480 |  | 
| 1476 1481 | 
             
              rb_iv_set(result, "@data", rb_str_new((char*)shared_secret->data, 32));
         | 
| @@ -1522,13 +1527,6 @@ Secp256k1_have_ecdh(VALUE module) | |
| 1522 1527 |  | 
| 1523 1528 | 
             
            void Init_rbsecp256k1()
         | 
| 1524 1529 | 
             
            {
         | 
| 1525 | 
            -
              // NOTE: All classes derive from Data (rb_cData) rather than Object
         | 
| 1526 | 
            -
              // (rb_cObject). This makes it so we don't have to call rb_undef_alloc_func
         | 
| 1527 | 
            -
              // for each class and can instead simply define the allocation methods for
         | 
| 1528 | 
            -
              // each class.
         | 
| 1529 | 
            -
              //
         | 
| 1530 | 
            -
              // See: https://github.com/ruby/ruby/blob/trunk/doc/extension.rdoc#encapsulate-c-data-into-a-ruby-object
         | 
| 1531 | 
            -
             | 
| 1532 1530 | 
             
              // Secp256k1
         | 
| 1533 1531 | 
             
              Secp256k1_module = rb_define_module("Secp256k1");
         | 
| 1534 1532 | 
             
              rb_define_singleton_method(
         | 
| @@ -1544,19 +1542,27 @@ void Init_rbsecp256k1() | |
| 1544 1542 | 
             
                0
         | 
| 1545 1543 | 
             
              );
         | 
| 1546 1544 |  | 
| 1545 | 
            +
              // Secp256k1 exception hierarchy
         | 
| 1546 | 
            +
              Secp256k1_Error_class = rb_define_class_under(
         | 
| 1547 | 
            +
                Secp256k1_module, "Error", rb_eStandardError
         | 
| 1548 | 
            +
              );
         | 
| 1549 | 
            +
              Secp256k1_SerializationError_class = rb_define_class_under(
         | 
| 1550 | 
            +
                Secp256k1_module, "SerializationError", Secp256k1_Error_class
         | 
| 1551 | 
            +
              );
         | 
| 1552 | 
            +
              Secp256k1_DeserializationError_class = rb_define_class_under(
         | 
| 1553 | 
            +
                Secp256k1_module, "DeserializationError", Secp256k1_Error_class
         | 
| 1554 | 
            +
              );
         | 
| 1555 | 
            +
             | 
| 1547 1556 | 
             
              // Secp256k1::Context
         | 
| 1548 1557 | 
             
              Secp256k1_Context_class = rb_define_class_under(
         | 
| 1549 | 
            -
                Secp256k1_module, "Context",  | 
| 1558 | 
            +
                Secp256k1_module, "Context", rb_cObject
         | 
| 1550 1559 | 
             
              );
         | 
| 1560 | 
            +
              rb_undef_alloc_func(Secp256k1_Context_class);
         | 
| 1551 1561 | 
             
              rb_define_alloc_func(Secp256k1_Context_class, Context_alloc);
         | 
| 1552 1562 | 
             
              rb_define_method(Secp256k1_Context_class,
         | 
| 1553 1563 | 
             
                               "initialize",
         | 
| 1554 1564 | 
             
                               Context_initialize,
         | 
| 1555 | 
            -
                                | 
| 1556 | 
            -
              rb_define_method(Secp256k1_Context_class,
         | 
| 1557 | 
            -
                               "generate_key_pair",
         | 
| 1558 | 
            -
                               Context_generate_key_pair,
         | 
| 1559 | 
            -
                               0);
         | 
| 1565 | 
            +
                               -1);
         | 
| 1560 1566 | 
             
              rb_define_method(Secp256k1_Context_class,
         | 
| 1561 1567 | 
             
                               "key_pair_from_private_key",
         | 
| 1562 1568 | 
             
                               Context_key_pair_from_private_key,
         | 
| @@ -1573,7 +1579,8 @@ void Init_rbsecp256k1() | |
| 1573 1579 | 
             
              // Secp256k1::KeyPair
         | 
| 1574 1580 | 
             
              Secp256k1_KeyPair_class = rb_define_class_under(Secp256k1_module,
         | 
| 1575 1581 | 
             
                                                              "KeyPair",
         | 
| 1576 | 
            -
                                                               | 
| 1582 | 
            +
                                                              rb_cObject);
         | 
| 1583 | 
            +
              rb_undef_alloc_func(Secp256k1_KeyPair_class);
         | 
| 1577 1584 | 
             
              rb_define_alloc_func(Secp256k1_KeyPair_class, KeyPair_alloc);
         | 
| 1578 1585 | 
             
              rb_define_attr(Secp256k1_KeyPair_class, "public_key", 1, 0);
         | 
| 1579 1586 | 
             
              rb_define_attr(Secp256k1_KeyPair_class, "private_key", 1, 0);
         | 
| @@ -1586,7 +1593,8 @@ void Init_rbsecp256k1() | |
| 1586 1593 | 
             
              // Secp256k1::PublicKey
         | 
| 1587 1594 | 
             
              Secp256k1_PublicKey_class = rb_define_class_under(Secp256k1_module,
         | 
| 1588 1595 | 
             
                                                                "PublicKey",
         | 
| 1589 | 
            -
                                                                 | 
| 1596 | 
            +
                                                                rb_cObject);
         | 
| 1597 | 
            +
              rb_undef_alloc_func(Secp256k1_PublicKey_class);
         | 
| 1590 1598 | 
             
              rb_define_alloc_func(Secp256k1_PublicKey_class, PublicKey_alloc);
         | 
| 1591 1599 | 
             
              rb_define_method(Secp256k1_PublicKey_class,
         | 
| 1592 1600 | 
             
                               "compressed",
         | 
| @@ -1606,8 +1614,9 @@ void Init_rbsecp256k1() | |
| 1606 1614 |  | 
| 1607 1615 | 
             
              // Secp256k1::PrivateKey
         | 
| 1608 1616 | 
             
              Secp256k1_PrivateKey_class = rb_define_class_under(
         | 
| 1609 | 
            -
                Secp256k1_module, "PrivateKey",  | 
| 1617 | 
            +
                Secp256k1_module, "PrivateKey", rb_cObject
         | 
| 1610 1618 | 
             
              );
         | 
| 1619 | 
            +
              rb_undef_alloc_func(Secp256k1_PrivateKey_class);
         | 
| 1611 1620 | 
             
              rb_define_alloc_func(Secp256k1_PrivateKey_class, PrivateKey_alloc);
         | 
| 1612 1621 | 
             
              rb_define_attr(Secp256k1_PrivateKey_class, "data", 1, 0);
         | 
| 1613 1622 | 
             
              rb_define_method(Secp256k1_PrivateKey_class, "==", PrivateKey_equals, 1);
         | 
| @@ -1621,7 +1630,8 @@ void Init_rbsecp256k1() | |
| 1621 1630 | 
             
              // Secp256k1::Signature
         | 
| 1622 1631 | 
             
              Secp256k1_Signature_class = rb_define_class_under(Secp256k1_module,
         | 
| 1623 1632 | 
             
                                                                "Signature",
         | 
| 1624 | 
            -
                                                                 | 
| 1633 | 
            +
                                                                rb_cObject);
         | 
| 1634 | 
            +
              rb_undef_alloc_func(Secp256k1_Signature_class);
         | 
| 1625 1635 | 
             
              rb_define_alloc_func(Secp256k1_Signature_class, Signature_alloc);
         | 
| 1626 1636 | 
             
              rb_define_method(Secp256k1_Signature_class,
         | 
| 1627 1637 | 
             
                               "der_encoded",
         | 
| @@ -1657,8 +1667,9 @@ void Init_rbsecp256k1() | |
| 1657 1667 | 
             
              Secp256k1_RecoverableSignature_class = rb_define_class_under(
         | 
| 1658 1668 | 
             
                Secp256k1_module,
         | 
| 1659 1669 | 
             
                "RecoverableSignature",
         | 
| 1660 | 
            -
                 | 
| 1670 | 
            +
                rb_cObject
         | 
| 1661 1671 | 
             
              );
         | 
| 1672 | 
            +
              rb_undef_alloc_func(Secp256k1_RecoverableSignature_class);
         | 
| 1662 1673 | 
             
              rb_define_alloc_func(
         | 
| 1663 1674 | 
             
                Secp256k1_RecoverableSignature_class,
         | 
| 1664 1675 | 
             
                RecoverableSignature_alloc
         | 
| @@ -1707,8 +1718,9 @@ void Init_rbsecp256k1() | |
| 1707 1718 | 
             
              Secp256k1_SharedSecret_class = rb_define_class_under(
         | 
| 1708 1719 | 
             
                Secp256k1_module,
         | 
| 1709 1720 | 
             
                "SharedSecret",
         | 
| 1710 | 
            -
                 | 
| 1721 | 
            +
                rb_cObject
         | 
| 1711 1722 | 
             
              );
         | 
| 1723 | 
            +
              rb_undef_alloc_func(Secp256k1_SharedSecret_class);
         | 
| 1712 1724 | 
             
              rb_define_alloc_func(Secp256k1_SharedSecret_class, SharedSecret_alloc);
         | 
| 1713 1725 | 
             
              rb_define_attr(Secp256k1_SharedSecret_class, "data", 1, 0);
         | 
| 1714 1726 |  | 
    
        data/lib/rbsecp256k1.rb
    CHANGED
    
    
| @@ -0,0 +1,29 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'securerandom'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Secp256k1
         | 
| 6 | 
            +
              # Wrapper around a secp256k1_context object.
         | 
| 7 | 
            +
              class Context
         | 
| 8 | 
            +
                # Create a new randomized context.
         | 
| 9 | 
            +
                #
         | 
| 10 | 
            +
                # @return [Secp256k1::Context] randomized context
         | 
| 11 | 
            +
                def self.create
         | 
| 12 | 
            +
                  new(context_randomization_bytes: SecureRandom.random_bytes(32))
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                # Create a new non-randomized context.
         | 
| 16 | 
            +
                #
         | 
| 17 | 
            +
                # @return [Secp256k1::Context] non-randomized context
         | 
| 18 | 
            +
                def self.create_unrandomized
         | 
| 19 | 
            +
                  new
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                # Generates a new random key pair.
         | 
| 23 | 
            +
                #
         | 
| 24 | 
            +
                # @return [Secp256k1::KeyPair] public-private key pair.
         | 
| 25 | 
            +
                def generate_key_pair
         | 
| 26 | 
            +
                  key_pair_from_private_key(SecureRandom.random_bytes(32))
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
            end
         | 
    
        data/lib/rbsecp256k1/util.rb
    CHANGED
    
    
    
        data/lib/rbsecp256k1/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: rbsecp256k1
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 5.0.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Eric Scrivner
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2019- | 
| 11 | 
            +
            date: 2019-06-08 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: mini_portile2
         | 
| @@ -100,14 +100,14 @@ dependencies: | |
| 100 100 | 
             
                requirements:
         | 
| 101 101 | 
             
                - - "~>"
         | 
| 102 102 | 
             
                  - !ruby/object:Gem::Version
         | 
| 103 | 
            -
                    version: '0. | 
| 103 | 
            +
                    version: '0.7'
         | 
| 104 104 | 
             
              type: :development
         | 
| 105 105 | 
             
              prerelease: false
         | 
| 106 106 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 107 107 | 
             
                requirements:
         | 
| 108 108 | 
             
                - - "~>"
         | 
| 109 109 | 
             
                  - !ruby/object:Gem::Version
         | 
| 110 | 
            -
                    version: '0. | 
| 110 | 
            +
                    version: '0.7'
         | 
| 111 111 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 112 112 | 
             
              name: yard
         | 
| 113 113 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -144,6 +144,7 @@ files: | |
| 144 144 | 
             
            - ext/rbsecp256k1/extconf.rb
         | 
| 145 145 | 
             
            - ext/rbsecp256k1/rbsecp256k1.c
         | 
| 146 146 | 
             
            - lib/rbsecp256k1.rb
         | 
| 147 | 
            +
            - lib/rbsecp256k1/context.rb
         | 
| 147 148 | 
             
            - lib/rbsecp256k1/util.rb
         | 
| 148 149 | 
             
            - lib/rbsecp256k1/version.rb
         | 
| 149 150 | 
             
            homepage: https://github.com/etscrivner/rbsecp256k1
         | 
| @@ -170,6 +171,6 @@ rubyforge_project: | |
| 170 171 | 
             
            rubygems_version: 2.7.6
         | 
| 171 172 | 
             
            signing_key: 
         | 
| 172 173 | 
             
            specification_version: 4
         | 
| 173 | 
            -
            summary:  | 
| 174 | 
            +
            summary: Native extension gem for secp256k1 ECDSA. Wraps libsecp256k1. In rbsecp256k1
         | 
| 174 175 | 
             
              3.0.0 and later libsecp256k1 is bundled with the gem.
         | 
| 175 176 | 
             
            test_files: []
         |