lib/tapyrus/secp256k1/ruby.rb in tapyrus-0.2.2 vs lib/tapyrus/secp256k1/ruby.rb in tapyrus-0.2.3
- old
+ new
@@ -29,11 +29,68 @@
# sign data.
# @param [String] data a data to be signed with binary format
# @param [String] privkey a private key using sign
# @return [String] signature data with binary format
- def sign_data(data, privkey, extra_entropy)
+ def sign_data(data, privkey, extra_entropy, algo: :ecdsa)
+ case algo
+ when :ecdsa
+ sign_ecdsa(data, privkey, extra_entropy)
+ when :schnorr
+ Schnorr.sign(data, privkey.to_i(16)).encode
+ else
+ nil
+ end
+ end
+
+ # verify signature using public key
+ # @param [String] digest a SHA-256 message digest with binary format
+ # @param [String] sig a signature for +data+ with binary format
+ # @param [String] pubkey a public key corresponding to the private key used for sign
+ # @return [Boolean] verify result
+ def verify_sig(digest, sig, pubkey, algo: :ecdsa)
+ case algo
+ when :ecdsa
+ verify_ecdsa(digest, sig, pubkey)
+ when :schnorr
+ Schnorr.valid_sig?(digest, sig, pubkey.htb)
+ else
+ false
+ end
+ end
+
+ alias :valid_sig? :verify_sig
+
+ module_function :valid_sig?
+
+ # validate whether this is a valid public key (more expensive than IsValid())
+ # @param [String] pubkey public key with hex format.
+ # @param [Boolean] allow_hybrid whether support hybrid public key.
+ # @return [Boolean] If valid public key return true, otherwise false.
+ def parse_ec_pubkey?(pubkey, allow_hybrid = false)
+ begin
+ point = ECDSA::Format::PointOctetString.decode(pubkey.htb, ECDSA::Group::Secp256k1, allow_hybrid: allow_hybrid)
+ ECDSA::Group::Secp256k1.valid_public_key?(point)
+ rescue ECDSA::Format::DecodeError
+ false
+ end
+ end
+
+ # if +pubkey+ is hybrid public key format, it convert uncompressed format.
+ # https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2012-June/001578.html
+ def repack_pubkey(pubkey)
+ p = pubkey.htb
+ case p[0]
+ when "\x06", "\x07"
+ p[0] = "\x04"
+ p
+ else
+ pubkey.htb
+ end
+ end
+
+ def sign_ecdsa(data, privkey, extra_entropy)
privkey = privkey.htb
private_key = ECDSA::Format::IntegerOctetString.decode(privkey)
extra_entropy ||= ''
nonce = RFC6979.generate_rfc6979_nonce(privkey + data, extra_entropy)
@@ -57,38 +114,16 @@
public_key = Tapyrus::Key.new(priv_key: privkey.bth).pubkey
raise 'Creation of signature failed.' unless Tapyrus::Secp256k1::Ruby.verify_sig(data, signature, public_key)
signature
end
- # verify signature using public key
- # @param [String] digest a SHA-256 message digest with binary format
- # @param [String] sig a signature for +data+ with binary format
- # @param [String] pubkey a public key corresponding to the private key used for sign
- # @return [Boolean] verify result
- def verify_sig(digest, sig, pubkey)
+ def verify_ecdsa(digest, sig, pubkey)
begin
k = ECDSA::Format::PointOctetString.decode(repack_pubkey(pubkey), GROUP)
signature = ECDSA::Format::SignatureDerString.decode(sig)
ECDSA.valid_signature?(k, digest, signature)
rescue Exception
false
- end
- end
-
- alias :valid_sig? :verify_sig
-
- module_function :valid_sig?
-
- # if +pubkey+ is hybrid public key format, it convert uncompressed format.
- # https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2012-June/001578.html
- def repack_pubkey(pubkey)
- p = pubkey.htb
- case p[0]
- when "\x06", "\x07"
- p[0] = "\x04"
- p
- else
- pubkey.htb
end
end
end