jose 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,188 @@
1
+ module JOSE::JWA::X25519
2
+
3
+ extend self
4
+
5
+ C_p = ((2 ** 255) - 19).to_bn.freeze
6
+ C_A = 486662.to_bn.freeze
7
+ C_order = ((2 ** 252) + 0x14def9dea2f79cd65812631a5cf5d3ed).to_bn.freeze
8
+ C_cofactor = 8.to_bn.freeze
9
+ C_u = 9.to_bn.freeze
10
+ C_v = 14781619447589544791020593568409986887264606134616475288964881837755586237401.to_bn.freeze
11
+ C_bits = 256.to_bn.freeze
12
+ C_bytes = ((C_bits + 7) / 8)[0].freeze
13
+ C_bit_steps = (C_bits-1).to_i.downto(0).to_a.freeze
14
+ C_byte_steps = (C_bytes-1).to_i.downto(0).to_a.freeze
15
+ C_a24 = ((C_A - 2) / 4)[0].freeze
16
+ C_scalarbytes = C_bytes
17
+ C_coordinatebytes = C_bytes
18
+ C_one = 1.to_bn.freeze
19
+ C_zero = 0.to_bn.freeze
20
+ C_F = JOSE::JWA::FieldElement.new(C_one, C_p).freeze
21
+ C_F_one = C_F
22
+ C_F_zero = C_F.make(C_zero).freeze
23
+ C_F_a24 = C_F.make(C_a24).freeze
24
+
25
+ def clamp_scalar(scalar)
26
+ scalar = coerce_coordinate_bytes!(scalar)
27
+ scalar.setbyte(0, scalar.getbyte(0) & 248)
28
+ scalar.setbyte(31, (scalar.getbyte(31) & 127) | 64)
29
+ return C_F.from_bytes(scalar, C_bits)
30
+ end
31
+
32
+ def cswap(swap, x_2, x_3)
33
+ iswap = (-swap.x.to_i) & 0xff
34
+ x_2 = x_2.to_bytes(C_bits)
35
+ x_3 = x_3.to_bytes(C_bits)
36
+ C_byte_steps.each do |i|
37
+ x_2i = x_2.getbyte(i)
38
+ x_3i = x_3.getbyte(i)
39
+ s = iswap & (x_2i ^ x_3i)
40
+ x_2.setbyte(i, x_2i ^ s)
41
+ x_3.setbyte(i, x_3i ^ s)
42
+ end
43
+ x_2 = C_F.from_bytes(x_2, C_bits)
44
+ x_3 = C_F.from_bytes(x_3, C_bits)
45
+ return x_2, x_3
46
+ end
47
+
48
+ def curve25519(k, u)
49
+ x_1 = u
50
+ x_2 = C_F_one
51
+ z_2 = C_F_zero
52
+ x_3 = u
53
+ z_3 = C_F_one
54
+ swap = C_F_zero
55
+
56
+ C_bit_steps.each do |t|
57
+ k_t = (k >> t) & 1
58
+ swap ^= k_t
59
+ x_2, x_3 = cswap(swap, x_2, x_3)
60
+ z_2, z_3 = cswap(swap, z_2, z_3)
61
+ swap = k_t
62
+
63
+ a = x_2 + z_2
64
+ aa = a.sqr
65
+ b = x_2 - z_2
66
+ bb = b.sqr
67
+ e = aa - bb
68
+ c = x_3 + z_3
69
+ d = x_3 - z_3
70
+ da = d * a
71
+ cb = c * b
72
+ x_3 = (da + cb).sqr
73
+ z_3 = x_1 * (da - cb).sqr
74
+ x_2 = aa * bb
75
+ z_2 = e * (aa + C_F_a24 * e)
76
+ end
77
+
78
+ x_2, x_3 = cswap(swap, x_2, x_3)
79
+ z_2, z_3 = cswap(swap, z_2, z_3)
80
+
81
+ return x_2 / z_2
82
+ end
83
+
84
+ def x25519(sk, pk)
85
+ u = coerce_coordinate_fe!(pk)
86
+ k = clamp_scalar(sk)
87
+ r = curve25519(k, u)
88
+ return r.to_bytes(C_bits)
89
+ end
90
+
91
+ def x25519_base(sk)
92
+ return x25519(sk, C_u)
93
+ end
94
+
95
+ def keypair(sk = nil)
96
+ sk ||= SecureRandom.random_bytes(C_bytes)
97
+ sk = clamp_scalar(sk)
98
+ pk = sk_to_pk(sk)
99
+ return pk, sk.to_bytes(C_bits)
100
+ end
101
+
102
+ def shared_secret(pk, sk)
103
+ return x25519(sk, pk)
104
+ end
105
+
106
+ def sk_to_pk(sk)
107
+ return x25519_base(sk)
108
+ end
109
+
110
+ def coerce_coordinate_bn!(coordinate)
111
+ raise ArgumentError, "coordinate size must be #{C_coordinatebytes} bytes" if not valid_coordinate?(coordinate)
112
+ coordinate = coordinate.value if coordinate.is_a?(JOSE::JWA::FieldElement)
113
+ coordinate = coordinate.to_bn if not coordinate.is_a?(OpenSSL::BN) and coordinate.respond_to?(:to_bn)
114
+ coordinate = OpenSSL::BN.new(coordinate.reverse, 2) if coordinate.respond_to?(:bytesize)
115
+ return coordinate
116
+ end
117
+
118
+ def coerce_scalar_bn!(scalar)
119
+ raise ArgumentError, "scalar size must be #{C_scalarbytes} bytes" if not valid_scalar?(scalar)
120
+ scalar = scalar.value if scalar.is_a?(JOSE::JWA::FieldElement)
121
+ scalar = scalar.to_bn if not scalar.is_a?(OpenSSL::BN) and scalar.respond_to?(:to_bn)
122
+ scalar = OpenSSL::BN.new(scalar.reverse, 2) if scalar.respond_to?(:bytesize)
123
+ return scalar
124
+ end
125
+
126
+ def coerce_coordinate_bytes!(coordinate)
127
+ raise ArgumentError, "coordinate size must be #{C_coordinatebytes} bytes" if not valid_coordinate?(coordinate)
128
+ coordinate = coordinate.to_bytes(C_bits) if coordinate.is_a?(JOSE::JWA::FieldElement)
129
+ coordinate = coordinate.to_bn if not coordinate.is_a?(OpenSSL::BN) and coordinate.respond_to?(:to_bn)
130
+ coordinate = coordinate.to_s(2).rjust(C_bytes, JOSE::JWA::ZERO_PAD).reverse if coordinate.is_a?(OpenSSL::BN)
131
+ return coordinate
132
+ end
133
+
134
+ def coerce_scalar_bytes!(scalar)
135
+ raise ArgumentError, "scalar size must be #{C_scalarbytes} bytes" if not valid_scalar?(scalar)
136
+ scalar = scalar.to_bytes(C_bits) if scalar.is_a?(JOSE::JWA::FieldElement)
137
+ scalar = scalar.to_bn if not scalar.is_a?(OpenSSL::BN) and scalar.respond_to?(:to_bn)
138
+ scalar = scalar.to_s(2).rjust(C_bytes, JOSE::JWA::ZERO_PAD).reverse if scalar.is_a?(OpenSSL::BN)
139
+ return scalar
140
+ end
141
+
142
+ def coerce_coordinate_fe!(coordinate)
143
+ return coordinate if coordinate.is_a?(JOSE::JWA::FieldElement) and coordinate.p == C_p
144
+ coordinate = coerce_coordinate_bn!(coordinate)
145
+ return C_F.make(coordinate)
146
+ end
147
+
148
+ def coerce_scalar_fe!(scalar)
149
+ return scalar if scalar.is_a?(JOSE::JWA::FieldElement) and scalar.p == C_p
150
+ scalar = coerce_scalar_bn!(scalar)
151
+ return C_F.make(scalar)
152
+ end
153
+
154
+ def valid_coordinate?(coordinate)
155
+ return true if coordinate.is_a?(JOSE::JWA::FieldElement) and coordinate.p == C_p
156
+ if not coordinate.is_a?(OpenSSL::BN) and coordinate.respond_to?(:to_bn)
157
+ coordinate = coordinate.to_bn
158
+ end
159
+ ubytes = 0
160
+ if coordinate.is_a?(OpenSSL::BN)
161
+ if coordinate.num_bytes > C_coordinatebytes
162
+ ubytes = coordinate.num_bytes
163
+ else
164
+ ubytes = C_coordinatebytes
165
+ end
166
+ end
167
+ ubytes = coordinate.bytesize if coordinate.respond_to?(:bytesize)
168
+ return !!(ubytes == C_coordinatebytes)
169
+ end
170
+
171
+ def valid_scalar?(scalar)
172
+ return true if scalar.is_a?(JOSE::JWA::FieldElement) and scalar.p == C_p
173
+ if not scalar.is_a?(OpenSSL::BN) and scalar.respond_to?(:to_bn)
174
+ scalar = scalar.to_bn
175
+ end
176
+ kbytes = 0
177
+ if scalar.is_a?(OpenSSL::BN)
178
+ if scalar.num_bytes > C_scalarbytes
179
+ kbytes = scalar.num_bytes
180
+ else
181
+ kbytes = C_scalarbytes
182
+ end
183
+ end
184
+ kbytes = scalar.bytesize if scalar.respond_to?(:bytesize)
185
+ return !!(kbytes == C_scalarbytes)
186
+ end
187
+
188
+ end
@@ -0,0 +1,35 @@
1
+ module JOSE::JWA::X25519_RbNaCl
2
+
3
+ extend self
4
+
5
+ def curve25519(k, u)
6
+ k = JOSE::JWA::X25519.coerce_scalar_bytes!(k) if not k.respond_to?(:bytesize)
7
+ u = RbNaCl::GroupElements::Curve25519.new(JOSE::JWA::X25519.coerce_coordinate_bytes!(u)) if not u.is_a?(RbNaCl::GroupElements::Curve25519)
8
+ return u.mult(k)
9
+ end
10
+
11
+ def x25519(sk, pk)
12
+ return curve25519(sk, pk).to_bytes
13
+ end
14
+
15
+ def x25519_base(sk)
16
+ sk = JOSE::JWA::X25519.coerce_scalar_bytes!(sk) if not sk.respond_to?(:bytesize)
17
+ return RbNaCl::GroupElements::Curve25519.base_point.mult(sk).to_bytes
18
+ end
19
+
20
+ def keypair(sk = nil)
21
+ sk ||= RbNaCl::Random.random_bytes(JOSE::JWA::X25519::C_bytes)
22
+ sk = JOSE::JWA::X25519.clamp_scalar(sk)
23
+ pk = sk_to_pk(sk)
24
+ return pk, sk.to_bytes(JOSE::JWA::X25519::C_bits)
25
+ end
26
+
27
+ def shared_secret(pk, sk)
28
+ return x25519(sk, pk)
29
+ end
30
+
31
+ def sk_to_pk(sk)
32
+ return x25519_base(sk)
33
+ end
34
+
35
+ end
@@ -0,0 +1,188 @@
1
+ module JOSE::JWA::X448
2
+
3
+ extend self
4
+
5
+ C_p = ((2 ** 448) - (2 ** 224) - 1).to_bn.freeze
6
+ C_A = 156326.to_bn.freeze
7
+ C_order = ((2 ** 446) + 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d).to_bn.freeze
8
+ C_cofactor = 4.to_bn.freeze
9
+ C_u = 5.to_bn.freeze
10
+ C_v = 355293926785568175264127502063783334808976399387714271831880898435169088786967410002932673765864550910142774147268105838985595290606362.to_bn.freeze
11
+ C_bits = 448.to_bn.freeze
12
+ C_bytes = ((C_bits + 7) / 8)[0].freeze
13
+ C_bit_steps = (C_bits-1).to_i.downto(0).to_a.freeze
14
+ C_byte_steps = (C_bytes-1).to_i.downto(0).to_a.freeze
15
+ C_a24 = ((C_A - 2) / 4)[0].freeze
16
+ C_scalarbytes = C_bytes
17
+ C_coordinatebytes = C_bytes
18
+ C_one = 1.to_bn.freeze
19
+ C_zero = 0.to_bn.freeze
20
+ C_F = JOSE::JWA::FieldElement.new(C_one, C_p).freeze
21
+ C_F_one = C_F
22
+ C_F_zero = C_F.make(C_zero).freeze
23
+ C_F_a24 = C_F.make(C_a24).freeze
24
+
25
+ def clamp_scalar(scalar)
26
+ scalar = coerce_coordinate_bytes!(scalar)
27
+ scalar.setbyte(0, scalar.getbyte(0) & 252)
28
+ scalar.setbyte(55, scalar.getbyte(55) | 128)
29
+ return C_F.from_bytes(scalar, C_bits)
30
+ end
31
+
32
+ def cswap(swap, x_2, x_3)
33
+ iswap = (-swap.x.to_i) & 0xff
34
+ x_2 = x_2.to_bytes(C_bits)
35
+ x_3 = x_3.to_bytes(C_bits)
36
+ C_byte_steps.each do |i|
37
+ x_2i = x_2.getbyte(i)
38
+ x_3i = x_3.getbyte(i)
39
+ s = iswap & (x_2i ^ x_3i)
40
+ x_2.setbyte(i, x_2i ^ s)
41
+ x_3.setbyte(i, x_3i ^ s)
42
+ end
43
+ x_2 = C_F.from_bytes(x_2, C_bits)
44
+ x_3 = C_F.from_bytes(x_3, C_bits)
45
+ return x_2, x_3
46
+ end
47
+
48
+ def curve448(k, u)
49
+ x_1 = u
50
+ x_2 = C_F_one
51
+ z_2 = C_F_zero
52
+ x_3 = u
53
+ z_3 = C_F_one
54
+ swap = C_F_zero
55
+
56
+ C_bit_steps.each do |t|
57
+ k_t = (k >> t) & 1
58
+ swap ^= k_t
59
+ x_2, x_3 = cswap(swap, x_2, x_3)
60
+ z_2, z_3 = cswap(swap, z_2, z_3)
61
+ swap = k_t
62
+
63
+ a = x_2 + z_2
64
+ aa = a.sqr
65
+ b = x_2 - z_2
66
+ bb = b.sqr
67
+ e = aa - bb
68
+ c = x_3 + z_3
69
+ d = x_3 - z_3
70
+ da = d * a
71
+ cb = c * b
72
+ x_3 = (da + cb).sqr
73
+ z_3 = x_1 * (da - cb).sqr
74
+ x_2 = aa * bb
75
+ z_2 = e * (aa + C_F_a24 * e)
76
+ end
77
+
78
+ x_2, x_3 = cswap(swap, x_2, x_3)
79
+ z_2, z_3 = cswap(swap, z_2, z_3)
80
+
81
+ return x_2 / z_2
82
+ end
83
+
84
+ def x448(sk, pk)
85
+ u = coerce_coordinate_fe!(pk)
86
+ k = clamp_scalar(sk)
87
+ r = curve448(k, u)
88
+ return r.to_bytes(C_bits)
89
+ end
90
+
91
+ def x448_base(sk)
92
+ return x448(sk, C_u)
93
+ end
94
+
95
+ def keypair(sk = nil)
96
+ sk ||= SecureRandom.random_bytes(C_bytes)
97
+ sk = clamp_scalar(sk)
98
+ pk = sk_to_pk(sk)
99
+ return pk, sk.to_bytes(C_bits)
100
+ end
101
+
102
+ def shared_secret(pk, sk)
103
+ return x448(sk, pk)
104
+ end
105
+
106
+ def sk_to_pk(sk)
107
+ return x448_base(sk)
108
+ end
109
+
110
+ def coerce_coordinate_bn!(coordinate)
111
+ raise ArgumentError, "coordinate size must be #{C_coordinatebytes} bytes" if not valid_coordinate?(coordinate)
112
+ coordinate = coordinate.value if coordinate.is_a?(JOSE::JWA::FieldElement)
113
+ coordinate = coordinate.to_bn if not coordinate.is_a?(OpenSSL::BN) and coordinate.respond_to?(:to_bn)
114
+ coordinate = OpenSSL::BN.new(coordinate.reverse, 2) if coordinate.respond_to?(:bytesize)
115
+ return coordinate
116
+ end
117
+
118
+ def coerce_scalar_bn!(scalar)
119
+ raise ArgumentError, "scalar size must be #{C_scalarbytes} bytes" if not valid_scalar?(scalar)
120
+ scalar = scalar.value if scalar.is_a?(JOSE::JWA::FieldElement)
121
+ scalar = scalar.to_bn if not scalar.is_a?(OpenSSL::BN) and scalar.respond_to?(:to_bn)
122
+ scalar = OpenSSL::BN.new(scalar.reverse, 2) if scalar.respond_to?(:bytesize)
123
+ return scalar
124
+ end
125
+
126
+ def coerce_coordinate_bytes!(coordinate)
127
+ raise ArgumentError, "coordinate size must be #{C_coordinatebytes} bytes" if not valid_coordinate?(coordinate)
128
+ coordinate = coordinate.to_bytes(C_bits) if coordinate.is_a?(JOSE::JWA::FieldElement)
129
+ coordinate = coordinate.to_bn if not coordinate.is_a?(OpenSSL::BN) and coordinate.respond_to?(:to_bn)
130
+ coordinate = coordinate.to_s(2).rjust(C_bytes, JOSE::JWA::ZERO_PAD).reverse if coordinate.is_a?(OpenSSL::BN)
131
+ return coordinate
132
+ end
133
+
134
+ def coerce_scalar_bytes!(scalar)
135
+ raise ArgumentError, "scalar size must be #{C_scalarbytes} bytes" if not valid_scalar?(scalar)
136
+ scalar = scalar.to_bytes(C_bits) if scalar.is_a?(JOSE::JWA::FieldElement)
137
+ scalar = scalar.to_bn if not scalar.is_a?(OpenSSL::BN) and scalar.respond_to?(:to_bn)
138
+ scalar = scalar.to_s(2).rjust(C_bytes, JOSE::JWA::ZERO_PAD).reverse if scalar.is_a?(OpenSSL::BN)
139
+ return scalar
140
+ end
141
+
142
+ def coerce_coordinate_fe!(coordinate)
143
+ return coordinate if coordinate.is_a?(JOSE::JWA::FieldElement) and coordinate.p == C_p
144
+ coordinate = coerce_coordinate_bn!(coordinate)
145
+ return C_F.make(coordinate)
146
+ end
147
+
148
+ def coerce_scalar_fe!(scalar)
149
+ return scalar if scalar.is_a?(JOSE::JWA::FieldElement) and scalar.p == C_p
150
+ scalar = coerce_scalar_bn!(scalar)
151
+ return C_F.make(scalar)
152
+ end
153
+
154
+ def valid_coordinate?(coordinate)
155
+ return true if coordinate.is_a?(JOSE::JWA::FieldElement) and coordinate.p == C_p
156
+ if not coordinate.is_a?(OpenSSL::BN) and coordinate.respond_to?(:to_bn)
157
+ coordinate = coordinate.to_bn
158
+ end
159
+ ubytes = 0
160
+ if coordinate.is_a?(OpenSSL::BN)
161
+ if coordinate.num_bytes > C_coordinatebytes
162
+ ubytes = coordinate.num_bytes
163
+ else
164
+ ubytes = C_coordinatebytes
165
+ end
166
+ end
167
+ ubytes = coordinate.bytesize if coordinate.respond_to?(:bytesize)
168
+ return !!(ubytes == C_coordinatebytes)
169
+ end
170
+
171
+ def valid_scalar?(scalar)
172
+ return true if scalar.is_a?(JOSE::JWA::FieldElement) and scalar.p == C_p
173
+ if not scalar.is_a?(OpenSSL::BN) and scalar.respond_to?(:to_bn)
174
+ scalar = scalar.to_bn
175
+ end
176
+ kbytes = 0
177
+ if scalar.is_a?(OpenSSL::BN)
178
+ if scalar.num_bytes > C_scalarbytes
179
+ kbytes = scalar.num_bytes
180
+ else
181
+ kbytes = C_scalarbytes
182
+ end
183
+ end
184
+ kbytes = scalar.bytesize if scalar.respond_to?(:bytesize)
185
+ return !!(kbytes == C_scalarbytes)
186
+ end
187
+
188
+ end
data/lib/jose/jwk.rb CHANGED
@@ -86,6 +86,27 @@ module JOSE
86
86
  return from_oct(File.binread(file), modules)
87
87
  end
88
88
 
89
+ def self.from_okp(object, modules = {})
90
+ raise ArgumentError, "object must be an Array of length 2" if not object.is_a?(Array) or object.length != 2
91
+ kty = modules[:kty] || case object[0]
92
+ when :Ed25519
93
+ JOSE::JWK::KTY_OKP_Ed25519
94
+ when :Ed25519ph
95
+ JOSE::JWK::KTY_OKP_Ed25519ph
96
+ when :Ed448
97
+ JOSE::JWK::KTY_OKP_Ed448
98
+ when :Ed448ph
99
+ JOSE::JWK::KTY_OKP_Ed448ph
100
+ when :X25519
101
+ JOSE::JWK::KTY_OKP_X25519
102
+ when :X448
103
+ JOSE::JWK::KTY_OKP_X448
104
+ else
105
+ raise ArgumentError, "unrecognized :okp object"
106
+ end
107
+ return JOSE::JWK.new(nil, *kty.from_okp(object))
108
+ end
109
+
89
110
  # Encode API
90
111
 
91
112
  def self.to_binary(jwk, key = nil, jwe = nil)
@@ -142,6 +163,14 @@ module JOSE
142
163
  return kty.to_oct
143
164
  end
144
165
 
166
+ def self.to_okp(jwk)
167
+ return from(jwk).to_okp
168
+ end
169
+
170
+ def to_okp
171
+ return kty.to_okp
172
+ end
173
+
145
174
  def self.to_pem(jwk, password = nil)
146
175
  return from(jwk).to_pem(password)
147
176
  end
@@ -254,6 +283,23 @@ module JOSE
254
283
  return JOSE::JWK.new(nil, *JOSE::JWK::KTY_EC.generate_key(params))
255
284
  when :oct
256
285
  return JOSE::JWK.new(nil, *JOSE::JWK::KTY_oct.generate_key(params))
286
+ when :okp
287
+ case params[1]
288
+ when :Ed25519
289
+ return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed25519.generate_key(params))
290
+ when :Ed25519ph
291
+ return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed25519ph.generate_key(params))
292
+ when :Ed448
293
+ return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed448.generate_key(params))
294
+ when :Ed448ph
295
+ return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_Ed448ph.generate_key(params))
296
+ when :X25519
297
+ return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_X25519.generate_key(params))
298
+ when :X448
299
+ return JOSE::JWK.new(nil, *JOSE::JWK::KTY_OKP_X448.generate_key(params))
300
+ else
301
+ raise ArgumentError, "invalid :okp key generation params"
302
+ end
257
303
  when :rsa
258
304
  return JOSE::JWK.new(nil, *JOSE::JWK::KTY_RSA.generate_key(params))
259
305
  else
@@ -272,6 +318,17 @@ module JOSE
272
318
  return JOSE::JWK.new(nil, *kty.generate_key(fields))
273
319
  end
274
320
 
321
+ def self.shared_secret(your_jwk, my_jwk)
322
+ return from(your_jwk).shared_secret(from(my_jwk))
323
+ end
324
+
325
+ def shared_secret(other_jwk)
326
+ other_jwk = from(other_jwk) if not other_jwk.is_a?(JOSE::JWK)
327
+ raise ArgumentError, "key types must match" if other_jwk.kty.class != kty.class
328
+ raise ArgumentError, "key type does not support shared secret computations" if not kty.respond_to?(:derive_key)
329
+ return kty.derive_key(other_jwk)
330
+ end
331
+
275
332
  def self.sign(jwk, plain_text, jws = nil, header = nil)
276
333
  return from(jwk).sign(plain_text, jws, header)
277
334
  end
@@ -325,6 +382,23 @@ module JOSE
325
382
  JOSE::JWK::KTY_EC
326
383
  when 'oct'
327
384
  JOSE::JWK::KTY_oct
385
+ when 'OKP'
386
+ case jwk.fields['crv']
387
+ when 'Ed25519'
388
+ JOSE::JWK::KTY_OKP_Ed25519
389
+ when 'Ed25519ph'
390
+ JOSE::JWK::KTY_OKP_Ed25519ph
391
+ when 'Ed448'
392
+ JOSE::JWK::KTY_OKP_Ed448
393
+ when 'Ed448ph'
394
+ JOSE::JWK::KTY_OKP_Ed448ph
395
+ when 'X25519'
396
+ JOSE::JWK::KTY_OKP_X25519
397
+ when 'X448'
398
+ JOSE::JWK::KTY_OKP_X448
399
+ else
400
+ raise ArgumentError, "unknown 'crv' for 'kty' of 'OKP': #{jwk.fields['crv'].inspect}"
401
+ end
328
402
  when 'RSA'
329
403
  JOSE::JWK::KTY_RSA
330
404
  else