Module: Tapyrus::Secp256k1::Ruby
- Defined in:
- lib/tapyrus/secp256k1/ruby.rb
Overview
secp256 module using ecdsa gem github.com/DavidEGrayson/ruby_ecdsa
Class Method Summary collapse
-
.generate_key(compressed: true) ⇒ Object
generate tapyrus key object.
-
.generate_key_pair(compressed: true) ⇒ Object
generate ec private key and public key.
- .generate_pubkey(privkey, compressed: true) ⇒ Object
-
.parse_ec_pubkey?(pubkey, allow_hybrid = false) ⇒ Boolean
validate whether this is a valid public key (more expensive than IsValid()).
-
.repack_pubkey(pubkey) ⇒ Object
if
pubkey
is hybrid public key format, it convert uncompressed format. -
.sign_data(data, privkey, extra_entropy, algo: :ecdsa) ⇒ String
sign data.
- .sign_ecdsa(data, privkey, extra_entropy) ⇒ Object
- .verify_ecdsa(digest, sig, pubkey) ⇒ Object
-
.verify_sig(digest, sig, pubkey, algo: :ecdsa) ⇒ Boolean
(also: valid_sig?)
verify signature using public key.
Class Method Details
.generate_key(compressed: true) ⇒ Object
generate tapyrus key object
18 19 20 21 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 18 def generate_key(compressed: true) privkey, pubkey = generate_key_pair(compressed: compressed) Tapyrus::Key.new(priv_key: privkey, pubkey: pubkey, compressed: compressed) end |
.generate_key_pair(compressed: true) ⇒ Object
generate ec private key and public key
9 10 11 12 13 14 15 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 9 def generate_key_pair(compressed: true) private_key = 1 + SecureRandom.random_number(GROUP.order - 1) public_key = GROUP.generator.multiply_by_scalar(private_key) privkey = ECDSA::Format::IntegerOctetString.encode(private_key, 32) pubkey = public_key.to_hex(compressed) [privkey.bth, pubkey] end |
.generate_pubkey(privkey, compressed: true) ⇒ Object
23 24 25 26 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 23 def generate_pubkey(privkey, compressed: true) public_key = ECDSA::Group::Secp256k1.generator.multiply_by_scalar(privkey.to_i(16)) public_key.to_hex(compressed) end |
.parse_ec_pubkey?(pubkey, allow_hybrid = false) ⇒ Boolean
validate whether this is a valid public key (more expensive than IsValid())
67 68 69 70 71 72 73 74 75 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 67 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 |
.repack_pubkey(pubkey) ⇒ Object
if pubkey
is hybrid public key format, it convert uncompressed format. lists.linuxfoundation.org/pipermail/bitcoin-dev/2012-June/001578.html
79 80 81 82 83 84 85 86 87 88 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 79 def repack_pubkey(pubkey) p = pubkey.htb case p[0] when "\x06", "\x07" p[0] = "\x04" p else pubkey.htb end end |
.sign_data(data, privkey, extra_entropy, algo: :ecdsa) ⇒ String
sign data.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 32 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 |
.sign_ecdsa(data, privkey, extra_entropy) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 90 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) # port form ecdsa gem. r_point = GROUP.new_point(nonce) point_field = ECDSA::PrimeField.new(GROUP.order) r = point_field.mod(r_point.x) return nil if r.zero? e = ECDSA.normalize_digest(data, GROUP.bit_length) s = point_field.mod(point_field.inverse(nonce) * (e + r * private_key)) if s > (GROUP.order / 2) # convert low-s s = GROUP.order - s end return nil if s.zero? signature = ECDSA::Signature.new(r, s).to_der 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_ecdsa(digest, sig, pubkey) ⇒ Object
119 120 121 122 123 124 125 126 127 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 119 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 |
.verify_sig(digest, sig, pubkey, algo: :ecdsa) ⇒ Boolean Also known as: valid_sig?
verify signature using public key
48 49 50 51 52 53 54 55 56 57 |
# File 'lib/tapyrus/secp256k1/ruby.rb', line 48 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 |