def ecdsa_signature(hash, privkey, normalized: true)
      raise ArgumentError, "Hash is missing" if !hash
      raise ArgumentError, "Private key is missing" if !privkey

      # ECDSA signature is a pair of numbers: (Kx, s)
      # Where Kx = x coordinate of k*G mod n (n is the order of secp256k1).
      # And s = (k^-1)*(h + Kx*privkey).
      # By default, k is chosen randomly on interval [0, n - 1].
      # But this makes signatures harder to test and allows faulty or
      # backdoored RNGs to leak private keys from ECDSA signatures.
      # To avoid these issues, we'll generate k = Hash256(hash || privatekey)
      # and make all computations by hand.

      autorelease do |pool|

        # Order of our curve
        n = self.group_order
        halfn = self.group_half_order

        # Generate k deterministically from private key and message using HMAC-SHA256
        # This is an important point #1.
        kdata = rfc6979_ecdsa_nonce(hash, privkey)
        k = pool.new_bn(kdata)

        # Enforce k within group order: k = k % n
        BN_div(nil, k, k, n, pool.bn_ctx)

        # Compute K = k*G
        #(can't use K variable name because Ruby does not allow
        # constant assignment in methods)
        kG = pool.new_ec_point
        EC_POINT_mul(self.group, kG, k, nil, nil, pool.bn_ctx)

        # Compute r = K.x. This is first half of the signature.
        r = pool.new_bn
        EC_POINT_get_affine_coordinates_GFp(self.group, kG, r, nil, pool.bn_ctx)

        # Compute s = (k^-1)*(h + r*privkey).
        h = pool.new_bn(hash)
        p = pool.new_bn(privkey)
        tmp = pool.new_bn
        s = pool.new_bn
        BN_mod_mul(tmp, r, p, n, pool.bn_ctx) # tmp = r*privkey
        BN_mod_add_quick(s, tmp, h, n)        # s = h + tmp = h + r*privkey
        BN_mod_inverse(k, k, n, pool.bn_ctx)  # k' = k^-1
        BN_mod_mul(s, s, k, n, pool.bn_ctx)   # s = k'*(h + r*privkey)

        # Enforce low S values, by negating the value (modulo the order) if above order/2.
        # This is an important point #2. Not doing that would yield (sometimes)
        # non-canonical signatures that will be rejected by many relaying nodes.
        if normalized
          if BN_cmp(s, halfn) > 0
            BN_sub(s, n, s)
          end
        end

        # Fill in ECDSA_SIG structure so we can convert it into a proper DER format.
        sig = ECDSA_SIG.new
        sig[:r] = r
        sig[:s] = s

        # Encode signature in DER format.

        sig_size = 72 # typical size of a signature (when both numbers are 33 bytes).

        # allocate a bit more memory just in case (cargo cult)
        buffer = FFI::MemoryPointer.new(:uint8, sig_size + 16)
        sig_size = i2d_ECDSA_SIG(sig.pointer, pointer_to_pointer(buffer))

        # read actual number of bytes composed by OpenSSL
        signature = buffer.read_string(sig_size)
        signature
      end
    end
def ecdsa_signature(hash, privkey, normalized: true)
      raise ArgumentError, "Hash is missing" if !hash
      raise ArgumentError, "Private key is missing" if !privkey

      # ECDSA signature is a pair of numbers: (Kx, s)
      # Where Kx = x coordinate of k*G mod n (n is the order of secp256k1).
      # And s = (k^-1)*(h + Kx*privkey).
      # By default, k is chosen randomly on interval [0, n - 1].
      # But this makes signatures harder to test and allows faulty or
      # backdoored RNGs to leak private keys from ECDSA signatures.
      # To avoid these issues, we'll generate k = Hash256(hash || privatekey)
      # and make all computations by hand.

      autorelease do |pool|

        # Order of our curve
        n = self.group_order
        halfn = self.group_half_order

        # Generate k deterministically from private key and message using HMAC-SHA256
        # This is an important point #1.
        kdata = rfc6979_ecdsa_nonce(hash, privkey)
        k = pool.new_bn(kdata)

        # Enforce k within group order: k = k % n
        BN_div(nil, k, k, n, pool.bn_ctx)

        # Compute K = k*G
        #(can't use K variable name because Ruby does not allow
        # constant assignment in methods)
        kG = pool.new_ec_point
        EC_POINT_mul(self.group, kG, k, nil, nil, pool.bn_ctx)

        # Compute r = K.x. This is first half of the signature.
        r = pool.new_bn
        EC_POINT_get_affine_coordinates_GFp(self.group, kG, r, nil, pool.bn_ctx)

        # Compute s = (k^-1)*(h + r*privkey).
        h = pool.new_bn(hash)
        p = pool.new_bn(privkey)
        tmp = pool.new_bn
        s = pool.new_bn
        BN_mod_mul(tmp, r, p, n, pool.bn_ctx) # tmp = r*privkey
        BN_mod_add_quick(s, tmp, h, n)        # s = h + tmp = h + r*privkey
        BN_mod_inverse(k, k, n, pool.bn_ctx)  # k' = k^-1
        BN_mod_mul(s, s, k, n, pool.bn_ctx)   # s = k'*(h + r*privkey)

        # Enforce low S values, by negating the value (modulo the order) if above order/2.
        # This is an important point #2. Not doing that would yield (sometimes)
        # non-canonical signatures that will be rejected by many relaying nodes.
        if normalized
          if BN_cmp(s, halfn) > 0
            BN_sub(s, n, s)
          end
        end

        # Fill in ECDSA_SIG structure so we can convert it into a proper DER format.
        sig = ECDSA_SIG.new
        sig[:r] = r
        sig[:s] = s

        # Encode signature in DER format.

        sig_size = 72 # typical size of a signature (when both numbers are 33 bytes).

        # allocate a bit more memory just in case (cargo cult)
        buffer = FFI::MemoryPointer.new(:uint8, sig_size + 16)
        sig_size = i2d_ECDSA_SIG(sig.pointer, pointer_to_pointer(buffer))

        # read actual number of bytes composed by OpenSSL
        signature = buffer.read_string(sig_size)
        signature
      end
    end
Computes a deterministic ECDSA signature with canonical (lowest) S value.
 Nonce k is equal to HMAC-SHA256(data: hash, key: privkey)