Skip to content

Commit f3f1c27

Browse files
authored
Merge pull request #22 from swift-libp2p/secp256+compressed
PeerID Spec Conformance
2 parents b576f55 + f97eee1 commit f3f1c27

File tree

4 files changed

+197
-188
lines changed

4 files changed

+197
-188
lines changed

Sources/LibP2PCrypto/Keys/KeyPair.swift

+34-2
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,48 @@ extension LibP2PCrypto.Keys {
178178
public init(marshaledPrivateKey str: String, base: BaseEncoding) throws {
179179
try self.init(marshaledPrivateKey: BaseEncoding.decode(str, as: base).data)
180180
}
181+
181182
/// Instantiate a KeyPair from a marshaled private key
183+
/// https://github.com/libp2p/specs/blob/master/peer-ids/peer-ids.md
182184
public init(marshaledPrivateKey data: Data) throws {
183185
let proto = try PrivateKey(contiguousBytes: data)
184186
switch proto.type {
185187
case .rsa:
186188
try self.init(privateKey: RSAPrivateKey(marshaledData: proto.data))
187189

188190
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+
}
191223
case .secp256K1:
192224
try self.init(privateKey: Secp256k1PrivateKey(marshaledData: proto.data))
193225
}

Sources/LibP2PCrypto/Keys/Types/Secp256k1/Secp256k1.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ extension Secp256k1PublicKey: CommonPublicKey {
5252
public func marshal() throws -> Data {
5353
var publicKey = PublicKey()
5454
publicKey.type = .secp256K1
55-
publicKey.data = self.rawRepresentation
55+
publicKey.data = try Data(self.compressPublicKey())
5656
return try publicKey.serializedData()
5757
}
5858

0 commit comments

Comments
 (0)