@@ -178,16 +178,48 @@ extension LibP2PCrypto.Keys {
178
178
public init ( marshaledPrivateKey str: String , base: BaseEncoding ) throws {
179
179
try self . init ( marshaledPrivateKey: BaseEncoding . decode ( str, as: base) . data)
180
180
}
181
+
181
182
/// Instantiate a KeyPair from a marshaled private key
183
+ /// https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md
182
184
public init ( marshaledPrivateKey data: Data ) throws {
183
185
let proto = try PrivateKey ( contiguousBytes: data)
184
186
switch proto. type {
185
187
case . rsa:
186
188
try self . init ( privateKey: RSAPrivateKey ( marshaledData: proto. data) )
187
189
188
190
case . ed25519:
189
- try self . init ( privateKey: Curve25519 . Signing. PrivateKey ( marshaledData: proto. data) )
190
-
191
+ switch proto. data. count {
192
+ case 32 :
193
+ try self . init ( privateKey: Curve25519 . Signing. PrivateKey ( marshaledData: proto. data) )
194
+ case 64 :
195
+ // [private key bytes][public key bytes]
196
+ // Ensure we can derive the attached public key
197
+ let privkey = try Curve25519 . Signing. PrivateKey ( marshaledData: proto. data. prefix ( 32 ) )
198
+ guard privkey. publicKey. rawRepresentation == proto. data. suffix ( 32 ) else {
199
+ throw NSError (
200
+ domain: " Invalid private key protobuf encoding -> unable to validate public key " ,
201
+ code: 0
202
+ )
203
+ }
204
+ try self . init ( privateKey: privkey)
205
+ case 96 :
206
+ // [private key][public key][public key]
207
+ // Ensure the two pubkeys match and we can derive the attached public key
208
+ let parts = Array ( proto. data. chunks ( ofCount: 32 ) )
209
+ guard parts [ 1 ] == parts [ 2 ] else {
210
+ throw NSError ( domain: " Invalid private key protobuf encoding -> pubkeys dont match " , code: 0 )
211
+ }
212
+ let privkey = try Curve25519 . Signing. PrivateKey ( marshaledData: parts [ 0 ] )
213
+ guard privkey. publicKey. rawRepresentation == parts [ 1 ] else {
214
+ throw NSError (
215
+ domain: " Invalid private key protobuf encoding -> unable to validate public key " ,
216
+ code: 0
217
+ )
218
+ }
219
+ try self . init ( privateKey: privkey)
220
+ default :
221
+ throw NSError ( domain: " Invalid private key protobuf encoding -> invalid data payload " , code: 0 )
222
+ }
191
223
case . secp256K1:
192
224
try self . init ( privateKey: Secp256k1PrivateKey ( marshaledData: proto. data) )
193
225
}
0 commit comments