             
             var outSize = 8192
             var result = Data(count:outSize)
-            let status = result.withUnsafeMutableBytes {
-                (resultBytes: UnsafeMutablePointer<UInt8>) -> CCCryptorStatus in
+            let status = result.withUnsafeMutableBytes { resultBytes in
                 return CCECCryptorComputeSharedSecret!(privKey, pubKey, resultBytes, &outSize)
             }
             guard status == noErr else { throw CCError(status) }
             
             result.count = outSize
             return result
+        }
+        
+        public struct KeyComponents {
+            public init(_ keySize: Int, _ x: Data, _ y: Data, _ d: Data) {
+                self.keySize = keySize
+                self.x = x
+                self.y = y
+                self.d = d
+            }
+            public var keySize: Int
+            public var x: Data
+            public var y: Data
+            public var d: Data
+        }
+        
+        public static func getPublicKeyComponents(_ keyData: Data) throws -> KeyComponents {
+            let key = try importKey(keyData, format: .binary, keyType: .keyPublic)
+            defer { CCECCryptorRelease!(key) }
+            return try getKeyComponents(key)
+        }
+        
+        public static func getPrivateKeyComponents(_ keyData: Data) throws -> KeyComponents {
+            let key = try importKey(keyData, format: .binary, keyType: .keyPrivate)
+            defer { CCECCryptorRelease!(key) }
+            return try getKeyComponents(key)
+        }
+        
+        fileprivate static func getKeyComponents(_ key: CCECCryptorRef) throws -> KeyComponents {
+            var keySize = 0, xSize = 8192, ySize = 8192, dSize = 8192
+            var x = Data(count: xSize), y = Data(count: ySize), d = Data(count: dSize)
+            let status = withUnsafePointers(&x, &y, &d, { xBytes, yBytes, dBytes in
+                return CCECCryptorGetKeyComponents!(key, &keySize,
+                                                    xBytes, &xSize,
+                                                    yBytes, &ySize,
+                                                    dBytes, &dSize)
+            })
+            guard status == noErr else { throw CCError(status) }
+            
+            x.count = xSize
+            y.count = ySize
+            d.count = dSize
+            if getKeyType(key) == .keyPublic {
+                d.count = 0
+            }
+            
+            return KeyComponents(keySize, x, y, d)
+        }
+        
+        public static func createFromData(_ keySize: size_t, _ x: Data, _ y: Data) throws -> Data {
+            var pubKey: CCECCryptorRef? = nil
+            
+            let status = withUnsafePointers(x, y, { xBytes, yBytes in
+                return CCECCryptorCreateFromData!(keySize, xBytes, x.count,
+                                                  yBytes, y.count, &pubKey)
+            })
+            guard status == noErr else { throw CCError(status) }
+            defer { CCECCryptorRelease!(pubKey!) }
+            
+            let pubKeyBin = try exportKey(pubKey!, format: .binary, type: .keyPublic)
+            return pubKeyBin
         }
         
         fileprivate static func importKey(_ key: Data, format: KeyExternalFormat,
                                           keyType: KeyType) throws -> CCECCryptorRef {
             var impKey: CCECCryptorRef? = nil
-            let status = CCECCryptorImportKey!(format.rawValue,
-                                               (key as NSData).bytes, key.count,
-                                               keyType.rawValue, &impKey)
+            let status = key.withUnsafeBytes { keyBytes in
+                return CCECCryptorImportKey!(format.rawValue,
+                                             keyBytes, key.count,
+                                             keyType.rawValue, &impKey)
+            }
             guard status == noErr else { throw CCError(status) }
             
             return impKey!

        }
    }
    
    open static func HMAC(_ data: Data, alg: HMACAlg, key: Data) -> Data {
        var buffer = Data(count: alg.digestLength)
        buffer.withUnsafeMutableBytes { (bufferBytes: UnsafeMutablePointer<UInt8>) -> Void in
            CCHmac!(alg.rawValue,
                    (key as NSData).bytes, key.count,
                    (data as NSData).bytes, data.count,
                    bufferBytes)
        }
        return buffer
    }
    

            precondition(data1.count == data2.count)
            
            var ret = Data(count: data1.count)
            let retcount = ret.count
            withUnsafePointers(data1, data2, &ret, {(
                b1: UnsafePointer<UInt8>,
                b2: UnsafePointer<UInt8>,
                r: UnsafeMutablePointer<UInt8>) in
                for i in 0 ..< retcount {
                    r[i] = b1[i] ^ b2[i]
                }
            })
            return ret
        }
        
