Class: Hive::CompactSigner::Rbsecp256k1

Inherits:
Object
  • Object
show all
Defined in:
lib/hive/compact_signer.rb

Constant Summary collapse

HEADER_BASE =
27
COMPRESSED_FLAG =
4

Instance Method Summary collapse

Constructor Details

#initializeRbsecp256k1

Returns a new instance of Rbsecp256k1.



7
8
9
10
11
12
13
14
15
16
17
# File 'lib/hive/compact_signer.rb', line 7

def initialize
  require 'rbsecp256k1'

  unless Secp256k1.have_recovery?
    raise Hive::BaseError, 'rbsecp256k1 was built without recoverable signature support'
  end

  @context = Secp256k1::Context.create
rescue LoadError => e
  raise Hive::BaseError, "rbsecp256k1 is not available: #{e.message}"
end

Instance Method Details

#public_key(private_key_hex, compressed = false) ⇒ Object



42
43
44
45
46
47
# File 'lib/hive/compact_signer.rb', line 42

def public_key(private_key_hex, compressed = false)
  keypair = @context.key_pair_from_private_key([private_key_hex].pack('H*'))
  public_key = keypair.public_key

  (compressed ? public_key.compressed : public_key.uncompressed).unpack1('H*')
end

#recover_compact(digest32, compact_signature) ⇒ Object



33
34
35
36
37
38
39
40
# File 'lib/hive/compact_signer.rb', line 33

def recover_compact(digest32, compact_signature)
  header = compact_signature.bytes.first
  recovery_id = header - HEADER_BASE
  recovery_id -= COMPRESSED_FLAG if recovery_id >= COMPRESSED_FLAG
  signature = @context.recoverable_signature_from_compact(compact_signature.byteslice(1, 64), recovery_id)

  signature.recover_public_key(digest32).uncompressed.unpack1('H*')
end

#sign_compact(digest32, private_key_hex, public_key_hex = nil, compressed = false) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/hive/compact_signer.rb', line 19

def sign_compact(digest32, private_key_hex, public_key_hex = nil, compressed = false)
  private_key = Secp256k1::PrivateKey.from_data([private_key_hex].pack('H*'))
  signature = @context.sign_recoverable(private_key, digest32)
  compact_signature, recovery_id = signature.compact
  header = HEADER_BASE + recovery_id + (compressed ? COMPRESSED_FLAG : 0)
  compact = [header].pack('C') + compact_signature

  if public_key_hex && public_key_hex != recover_compact(digest32, compact)
    raise Hive::BaseError, 'Compact signature recovered unexpected public key'
  end

  compact
end