File: ed25519.rb

package info (click to toggle)
ruby-ssh-data 1.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 184 kB
  • sloc: ruby: 1,483; makefile: 4
file content (68 lines) | stat: -rw-r--r-- 1,907 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
module SSHData
  module PrivateKey
    class ED25519 < Base
      attr_reader :pk, :sk, :ed25519_key

      # Generate a new private key.
      #
      # Returns a PublicKey::Base subclass instance.
      def self.generate
        PublicKey::ED25519.ed25519_gem_required!
        from_ed25519(Ed25519::SigningKey.generate)
      end

      # Create from a ::Ed25519::SigningKey instance.
      #
      # key - A ::Ed25519::SigningKey instance.
      #
      # Returns a ED25519 instance.
      def self.from_ed25519(key)
        new(
          algo: PublicKey::ALGO_ED25519,
          pk: key.verify_key.to_bytes,
          sk: key.to_bytes + key.verify_key.to_bytes,
          comment: "",
        )
      end

      def initialize(algo:, pk:, sk:, comment:)
        unless algo == PublicKey::ALGO_ED25519
          raise DecodeError, "bad algorithm: #{algo.inspect}"
        end

        # openssh stores the pk twice, once as half of the sk...
        if sk.bytesize != 64 || sk.byteslice(32, 32) != pk
          raise DecodeError, "bad sk"
        end

        @pk = pk
        @sk = sk

        super(algo: algo, comment: comment)

        if PublicKey::ED25519.enabled?
          @ed25519_key = Ed25519::SigningKey.new(sk.byteslice(0, 32))

          if @ed25519_key.verify_key.to_bytes != pk
            raise DecodeError, "bad pk"
          end
        end

        @public_key = PublicKey::ED25519.new(algo: algo, pk: pk)
      end

      # Make an SSH signature.
      #
      # signed_data - The String message over which to calculated the signature.
      #
      # Returns a binary String signature.
      def sign(signed_data, algo: nil)
        PublicKey::ED25519.ed25519_gem_required!
        algo ||= self.algo
        raise AlgorithmError unless algo == self.algo
        raw_sig = ed25519_key.sign(signed_data)
        Encoding.encode_signature(algo, raw_sig)
      end
    end
  end
end