Module: Ed448

Extended by:
FFI::Library
Defined in:
lib/ed448.rb,
lib/ed448/x448.rb,
lib/ed448/version.rb

Defined Under Namespace

Modules: X448

Constant Summary collapse

EDDSA_448_PUBLIC_BYTES =
57
EDDSA_448_PRIVATE_BYTES =
57
EDDSA_448_SIGNATURE_BYTES =
EDDSA_448_PRIVATE_BYTES + EDDSA_448_PUBLIC_BYTES
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.derive_public_key(private_key) ⇒ Object



125
126
127
128
129
130
# File 'lib/ed448.rb', line 125

def derive_public_key(private_key)
  private_key = FFI::MemoryPointer.new(:uchar, EDDSA_448_PRIVATE_BYTES).put_bytes(0, private_key)
  public_key = FFI::MemoryPointer.new(:uchar, EDDSA_448_PUBLIC_BYTES)
  goldilocks_ed448_derive_public_key(public_key, private_key)
  public_key.read_string(EDDSA_448_PUBLIC_BYTES)
end

.initObject

macOS ENV = ‘/usr/local/lib/libgoldilocks.dylib’

Raises:

  • (LoadError)


18
19
20
21
22
23
24
# File 'lib/ed448.rb', line 18

def init
  raise LoadError unless ENV['LIBGOLDILOCKS']
  raise LoadError unless File.exist?(ENV['LIBGOLDILOCKS'])

  ffi_lib(ENV['LIBGOLDILOCKS'])
  load_functions
end

.load_functionsObject



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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
118
119
120
121
122
123
# File 'lib/ed448.rb', line 26

def load_functions
  # @brief EdDSA key generation.  This function uses a different (non-Decaf)
  # encoding.
  #     
  # @param [out] pubkey The public key.
  # @param [in] privkey The private key.
  #
  # void goldilocks_ed448_derive_public_key (
  #     uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
  #     const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES]
  # )
  attach_function(:goldilocks_ed448_derive_public_key, [:pointer, :pointer], :void)

  # @brief EdDSA signing.
  #
  # @param [out] signature The signature.
  # @param [in] privkey The private key.
  # @param [in] pubkey The public key.
  # @param [in] message The message to sign.
  # @param [in] message_len The length of the message.
  # @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign.
  # @param [in] context A "context" for this signature of up to 255 bytes.
  # @param [in] context_len Length of the context.
  #
  # @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed
  # messages, at least without some very careful protocol-level disambiguation.  For Ed448 it is
  # safe.  The C++ wrapper is designed to make it harder to screw this up, but this C code gives
  # you no seat belt.
  # void goldilocks_ed448_sign (
  #   uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
  #   const uint8_t privkey[GOLDILOCKS_EDDSA_448_PRIVATE_BYTES],
  #   const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
  #   const uint8_t *message,
  #   size_t message_len,
  #   uint8_t prehashed,
  #   const uint8_t *context,
  #   uint8_t context_len
  # )
  attach_function(:goldilocks_ed448_sign, [:pointer, :pointer, :pointer, :pointer,:int, :int, :pointer, :int], :void)

  # @brief EdDSA signature verification.
  #
  # Uses the standard (i.e. less-strict) verification formula.
  #
  # @param [in] signature The signature.
  # @param [in] pubkey The public key.
  # @param [in] message The message to verify.
  # @param [in] message_len The length of the message.
  # @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify.
  # @param [in] context A "context" for this signature of up to 255 bytes.
  # @param [in] context_len Length of the context.
  #
  # @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed
  # messages, at least without some very careful protocol-level disambiguation.  For Ed448 it is
  # safe.  The C++ wrapper is designed to make it harder to screw this up, but this C code gives
  # you no seat belt.
  #
  # goldilocks_error_t goldilocks_ed448_verify (
  #     const uint8_t signature[GOLDILOCKS_EDDSA_448_SIGNATURE_BYTES],
  #     const uint8_t pubkey[GOLDILOCKS_EDDSA_448_PUBLIC_BYTES],
  #     const uint8_t *message,
  #     size_t message_len,
  #     uint8_t prehashed,
  #     const uint8_t *context,
  #     uint8_t context_len
  # )
  attach_function(:goldilocks_ed448_verify, [:pointer, :pointer, :pointer,:int, :int, :pointer, :int], :int)

  # @brief RFC 7748 Diffie-Hellman scalarmul, used to compute shared secrets.
  # This function uses a different (non-Decaf) encoding.
  #
  # @param [out] shared The shared secret base*scalar
  # @param [in] base The other party's public key, used as the base of the scalarmul.
  # @param [in] scalar The private scalar to multiply by.
  #
  # @retval GOLDILOCKS_SUCCESS The scalarmul succeeded.
  # @retval GOLDILOCKS_FAILURE The scalarmul didn't succeed, because the base
  # point is in a small subgroup.
  #
  # goldilocks_error_t goldilocks_x448 (
  #     uint8_t shared[GOLDILOCKS_X448_PUBLIC_BYTES],
  #     const uint8_t base[GOLDILOCKS_X448_PUBLIC_BYTES],
  #     const uint8_t scalar[GOLDILOCKS_X448_PRIVATE_BYTES]
  # ) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_WARN_UNUSED GOLDILOCKS_NOINLINE;
  attach_function(:goldilocks_x448, [:pointer, :pointer, :pointer], :int)

  # @brief RFC 7748 Diffie-Hellman base point scalarmul.  This function uses
  # a different (non-Decaf) encoding.
  #
  # @param [out] out The public key base*scalar
  # @param [in] scalar The private scalar.
  #
  # void goldilocks_x448_derive_public_key (
  #     uint8_t out[GOLDILOCKS_X448_PUBLIC_BYTES],
  #     const uint8_t scalar[GOLDILOCKS_X448_PRIVATE_BYTES]
  # ) GOLDILOCKS_API_VIS GOLDILOCKS_NONNULL GOLDILOCKS_NOINLINE;
  attach_function(:goldilocks_x448_derive_public_key, [:pointer, :pointer], :void)
end

.sign(private_key, public_key, message) ⇒ Object



132
133
134
135
136
137
138
139
140
141
# File 'lib/ed448.rb', line 132

def sign(private_key, public_key, message)
  signature = FFI::MemoryPointer.new(:uchar, EDDSA_448_SIGNATURE_BYTES)
  private_key = FFI::MemoryPointer.new(:uchar, EDDSA_448_PRIVATE_BYTES).put_bytes(0, private_key)
  public_key = FFI::MemoryPointer.new(:uchar, EDDSA_448_PUBLIC_BYTES).put_bytes(0, public_key)
  message_len = message.bytesize
  message = FFI::MemoryPointer.new(:uchar, message_len).put_bytes(0, message)
  context = FFI::MemoryPointer.new(:uchar, 0)
  goldilocks_ed448_sign(signature, private_key, public_key, message, message_len, 0, context, 0)
  signature.read_string(EDDSA_448_SIGNATURE_BYTES)
end

.verify(signature, public_key, message) ⇒ Object



143
144
145
146
147
148
149
150
151
# File 'lib/ed448.rb', line 143

def verify(signature, public_key, message)
  signature = FFI::MemoryPointer.new(:uchar, EDDSA_448_SIGNATURE_BYTES).put_bytes(0, signature)
  public_key = FFI::MemoryPointer.new(:uchar, EDDSA_448_PUBLIC_BYTES).put_bytes(0, public_key)
  message_len = message.bytesize
  message = FFI::MemoryPointer.new(:uchar, message_len).put_bytes(0, message)
  context = FFI::MemoryPointer.new(:uchar, 0)
  result = goldilocks_ed448_verify(signature, public_key, message, message_len, 0, context, 0)
  result == -1
end