V0.7.0 Arroyo Toad

Added Factory to help the creation of EdgeDevices
This commit is contained in:
Christian Risi 2024-12-10 17:58:01 +01:00
parent 92875ecb12
commit 569b29c815
9 changed files with 106 additions and 176 deletions

View File

@ -15,12 +15,17 @@ public class EdgeDevice: EdgeDeviceP {
public var dutyCicle: UInt
public var sensors: [Int: Sensor]
public var privateKey: P256.Signing.PrivateKey
public var publicKey: P256.Signing.PublicKey {
get{
return self.privateKey.publicKey
}
}
private var numberOfSensors: Int {
return sensors.count
}
public init(
internal init(
deviceID: UInt128,
dataType: DataType,
disconnected: Bool,

View File

@ -1,4 +1,4 @@
public enum DataType : Sendable{
public enum DataType : String{
case Temperature
case Humidity
case Scan

View File

@ -1,4 +1,8 @@
public enum CoreError : Error {
case NoPhysicalDataAvailable( dataType: String)
case NoEnvironment
case NoJSONDevice
case DeviceIDAlreadyExsitent
case InvalidDeviceID
case FinishedIDs
}

View File

@ -0,0 +1,93 @@
import Crypto
import MessageUtils
public actor DeviceFactory {
private static var setted: Bool = false
private static var availableIDs: Set<UInt128> = Set(0..<999)
public static func createEdgeDevice(
dataType: DataType,
privateKey: P256.Signing.PrivateKey
) throws -> EdgeDevice{
return try DeviceFactory.createEdgeDevice(
dataType: dataType,
privateKey: privateKey,
realSensor: false
)
}
public static func createEdgeDevice(
dataType: DataType,
privateKey: P256.Signing.PrivateKey,
realSensor: Bool
) throws -> EdgeDevice{
let deviceID = try DeviceFactory.getUnusedID()
return try DeviceFactory.createEdgeDevice(
deviceID: deviceID,
dataType: dataType,
location: Location(
x: UInt64.random(in: 0...10000),
y: UInt64.random(in: 0...10000),
z: UInt64.random(in: 0...10000)
),
dutyCicle: UInt.random(in: 0...5000),
privateKey: privateKey,
realSensor: realSensor
)
}
public static func createEdgeDevice(
deviceID: UInt128,
dataType: DataType,
location: Location,
dutyCicle: UInt,
privateKey: P256.Signing.PrivateKey,
realSensor: Bool
) throws -> EdgeDevice {
if !DeviceFactory.availableIDs.contains(deviceID) {
throw CoreError.InvalidDeviceID
}
DeviceFactory.availableIDs.remove(deviceID)
// Create sensors here
let sensors : [Int: Sensor]
if !realSensor {
sensors = [
0: Sensor(id: 0, sensorType: dataType),
1: Sensor(id: 1, sensorType: dataType),
2: Sensor(id: 2, sensorType: dataType)
]
} else {
sensors = [
0: RealSensor(sensorID: 0, sensorType: dataType, faulty: false, meanNoise: 0, stdNoise: 0.5, quantizationBits: 8),
1: RealSensor(sensorID: 1, sensorType: dataType, faulty: false, meanNoise: 0, stdNoise: 0.5, quantizationBits: 8),
2: RealSensor(sensorID: 2, sensorType: dataType, faulty: false, meanNoise: 0, stdNoise: 0.5, quantizationBits: 8)
]
}
return EdgeDevice(
deviceID: deviceID,
dataType: dataType,
disconnected: false,
location: location,
dutyCicle: dutyCicle,
sensors: sensors,
privateKey: privateKey)
}
private static func getUnusedID() throws -> UInt128 {
if DeviceFactory.availableIDs.count < 1 {
throw CoreError.FinishedIDs
}
return DeviceFactory.availableIDs.removeFirst()
}
}

View File

@ -12,6 +12,7 @@ public protocol EdgeDeviceP {
var compromised : Bool {get set}
var dutyCicle : UInt {get set}
var privateKey: P256.Signing.PrivateKey {get}
var publicKey: P256.Signing.PublicKey {get}
func work(envrionment: PhysicalEnvironment) throws -> Data

View File

@ -1,82 +0,0 @@
import Crypto // Equivalent to CryptoKit (more or less)
import Foundation
// ------------------
// --- Sign ---------
// ------------------
public func sign(string: String, key: P521.Signing.PrivateKey) throws -> String {
let data = Data(string.utf8)
return try sign(object: data, key: key)
}
public func sign(object: Data, key: P521.Signing.PrivateKey)throws -> String {
return try key.signature<Data>(for: object).rawRepresentation.base64EncodedString()
}
/*
public func sign<T>(object: T, key: P521.Signing.PrivateKey) throws -> String {
var _object = object
let data: Data = Data(bytes: &_object, count: MemoryLayout<T>.stride)
} */
// ------------------
// --- Decrypt ------
// ------------------
public func verifySignature(signature: String, string: String, key: P521.Signing.PublicKey) throws -> Bool {
let data = Data(string.utf8)
let ecdsa: P521.Signing.ECDSASignature
do {
let bytes = Data(base64Encoded: signature)!
ecdsa = try P521.Signing.ECDSASignature(rawRepresentation: bytes)
} catch {
throw SecurityError.NotDecodableError
}
return key.isValidSignature<Data>(ecdsa, for: data)
}
public func verifySignature(signature: String, object: Data, key: P521.Signing.PublicKey) throws -> Bool {
let ecdsa: P521.Signing.ECDSASignature
do {
let bytes = Data(base64Encoded: signature)!
ecdsa = try P521.Signing.ECDSASignature(rawRepresentation: bytes)
} catch {
throw SecurityError.NotDecodableError
}
return key.isValidSignature<Data>(ecdsa, for: object)
}
// ------------------
// --- PEM 2 Key ----
// ------------------
public func pem2key(filePath: String) throws -> P521.Signing.PrivateKey {
let pemURL: URL = URL(filePath: filePath)
return try pem2key(filePem: pemURL)
}
public func pem2key(filePem: URL) throws -> P521.Signing.PrivateKey {
let fileString: String = try String(contentsOf: filePem, encoding: String.Encoding.utf8)
return try pem2key(pemString: fileString)
}
public func pem2key(pemString: String) throws -> P521.Signing.PrivateKey {
return try P521.Signing.PrivateKey(pemRepresentation: pemString)
}

View File

@ -1,28 +0,0 @@
import Foundation
public func meanValue<Numerical: FloatingPoint>(values: [Numerical]) -> Numerical{
var avg : Numerical = 0
for i in 0..<values.count {
avg += values[i]
}
return avg / Numerical(values.count)
}
// UGLY Find a way to implement power protocol, if issues with optimization
public func standardDeviation<Numerical: FloatingPoint>(values: [Numerical]) -> Numerical{
let avg : Numerical = meanValue(values: values)
var summatory: Numerical = 0
for i in 0..<values.count {
let intermediate = (values[i] - avg)
summatory += (intermediate * intermediate)
}
return sqrt(
summatory / Numerical(values.count)
)
}

View File

@ -81,7 +81,7 @@ import MessageUtils
@Test func stressLoop1() async throws {
let devices: UInt128 = 600
let devices: UInt128 = 500
let env = PhysicalEnvironment("Delta")
let truth = PhysicalData(.Temperature, 22)

View File

@ -1,63 +0,0 @@
import Testing
import RandomCpp
import Foundation
import Crypto
@testable import IoT_Simulator_Core
@Test func workingGeneratorTest() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
var a = GaussianRNG(10, 0.5)
for _ in 0...10 {
print(a.generate())
}
}
@Test func pemDecoded() async throws {
/*
Even though here you would expect both texts to be equal,
the openssl generated one (the raw string) is ANSI x9.62
while ours (the one made with the library) is ASN.1
When inspected with openssl, both curves where identical,
so no need to be worried
*/
let keyPath = "./Private/privateKey.pem"
let url = URL(filePath: keyPath)
let pemString = try String(contentsOf: url, encoding: String.Encoding.utf8)
let key = try pem2key(filePath: keyPath)
print(pemString)
print(key.pemRepresentation)
}
@Test func sign() async throws {
let keyPath = "./Private/privateKey.pem"
let key = try pem2key(filePath: keyPath)
let obj = "[1, 2, 3] "
let signature = try sign(string: obj, key: key)
print(signature)
}
@Test func verifySignature() async throws {
let keyPath = "./Private/privateKey.pem"
let key = try pem2key(filePath: keyPath)
let obj = "[1, 2, 3] "
let signature = try sign(string: obj, key: key)
let puKey = key.publicKey
let _verify = try verifySignature(signature: signature, string: obj, key: puKey)
print(_verify)
assert(_verify)
}