jose 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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