Class: FlowClient::Crypto

Inherits:
Object
  • Object
show all
Defined in:
lib/flow_client/crypto.rb

Overview

Crypto helpers

Defined Under Namespace

Modules: Curves, HashAlgos

Class Method Summary collapse

Class Method Details

.generate_key_pair(curve = Curves::P256) ⇒ Object

Returns an octet string keypair.

Supported ECC curves are: Crypto::Curves::P256 Crypto::Curves::SECP256K1

The 04 prefix indicating that the public key is uncompressed is stripped. datatracker.ietf.org/doc/html/rfc5480

Usage example: private_key, public_key = FlowClient::Crypto.generate_key_pair(FlowClient::Crypto::Curves::P256)


53
54
55
56
57
58
59
60
# File 'lib/flow_client/crypto.rb', line 53

def self.generate_key_pair(curve = Curves::P256)
  key = OpenSSL::PKey::EC.new(curve).generate_key
  public_key = key.public_key.to_bn.to_s(16).downcase
  [
    key.private_key.to_s(16).downcase,
    public_key[2..public_key.length]
  ]
end

.key_from_hex_keys(private_hex, curve = Curves::P256) ⇒ Object

Constructs an OpenSSL::PKey::EC key from an octet string keypair.

secp256k1 prime256v1


34
35
36
37
38
39
40
# File 'lib/flow_client/crypto.rb', line 34

def self.key_from_hex_keys(private_hex, curve = Curves::P256)
  group = OpenSSL::PKey::EC::Group.new(curve)
  new_key = OpenSSL::PKey::EC.new(group)
  new_key.private_key = OpenSSL::BN.new(private_hex, 16)
  new_key.public_key = group.generator.mul(new_key.private_key)
  new_key
end

.sign(data, private_key_hex, hash_algo = HashAlgos::SHA3_256) ⇒ Object

Sign data using the provided key


19
20
21
22
23
24
25
26
27
# File 'lib/flow_client/crypto.rb', line 19

def self.sign(data, private_key_hex, hash_algo = HashAlgos::SHA3_256)
  ssl_key = FlowClient::Crypto.key_from_hex_keys(private_key_hex)
  # TODO: Fix this so that both hashing algos will work
  asn = ssl_key.dsa_sign_asn1(OpenSSL::Digest.digest("SHA3-256", data))
  r, s = OpenSSL::ASN1.decode(asn).value
  combined_bytes = Utils.left_pad_bytes([r.value.to_s(16)].pack("H*").unpack("C*"), 32) +
                   Utils.left_pad_bytes([s.value.to_s(16)].pack("H*").unpack("C*"), 32)
  combined_bytes.pack("C*")
end