V0.6.0 Arroyo Toad

Added the capability to sign and verify P521 Signature
This commit is contained in:
Christian Risi
2024-12-06 11:31:07 +00:00
parent 6859e27368
commit ad4fd555f1
25 changed files with 764 additions and 537 deletions

View File

@@ -0,0 +1,58 @@
import Crypto // Equivalent to CryptoKit (more or less)
import Foundation
// ------------------
// --- Sign ---------
// ------------------
public func signP521(object: Data, key: P521.Signing.PrivateKey)throws -> Data {
return try key.signature<Data>(for: object).rawRepresentation
}
/*
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 verifySignatureP521(signature: Data, object: Data, key: P521.Signing.PublicKey) throws -> Bool {
let ecdsa: P521.Signing.ECDSASignature
do {
ecdsa = try P521.Signing.ECDSASignature(rawRepresentation: signature)
} 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

@@ -0,0 +1,4 @@
enum SecurityError: Error {
case NotEncodableError
case NotDecodableError
}

View File

@@ -1,5 +1,5 @@
import Foundation
public protocol DataCompatibleP {
var data : Data {get}
import Foundation
public protocol DataCompatibleP {
var data : Data {get}
}

View File

@@ -1,32 +1,32 @@
import Foundation
public extension Data {
var uint8 : UInt8 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt8.self) }[0]
}
var uint16: UInt16 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt16.self) }[0]
}
var uint32: UInt32 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt32.self) }[0]
}
var uint64: UInt64 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt64.self) }[0]
}
var uint128: UInt128 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt128.self) }[0]
}
var uint: UInt {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt.self) }[0]
}
var timestamp: Date {
return self.withUnsafeBytes{ $0.bindMemory(to: Date.self) }[0]
}
import Foundation
public extension Data {
var uint8 : UInt8 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt8.self) }[0]
}
var uint16: UInt16 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt16.self) }[0]
}
var uint32: UInt32 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt32.self) }[0]
}
var uint64: UInt64 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt64.self) }[0]
}
var uint128: UInt128 {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt128.self) }[0]
}
var uint: UInt {
return self.withUnsafeBytes{ $0.bindMemory(to: UInt.self) }[0]
}
var timestamp: Date {
return self.withUnsafeBytes{ $0.bindMemory(to: Date.self) }[0]
}
}

View File

@@ -1,52 +1,61 @@
# Message Structure
```
+-+ 64 - bits---+----------------+-------------+----------------+-----------------------+
|0| Version 7 | Message Type 8 | Dev Type 8 | RESERVED 16 | Sign Type 32 |
+-+-------------+----------------+-------------+----------------+-----------------------+
| Timestamp 64 |
+---------------------------------------------------------------------------------------+
| DevID 128 bits |
| |
+---------------------------------------------------------------------------------------+
| Location 192 bits |
| |
| |
+---------------------------------------------------------------------------------------+
\ /
| Fields -----------------------------------------------------------------------------|
/ \
+---------------------------------------------------------------------------------------+
| 0 Padding 64 - n |
+---------------------------------------------------------------------------------------+
| Signature up to-512 bits |
| |
| |
| |
| |
| |
| |
| |
+---------------------------------------------------------------------------------------+
```
# Fields
each field can be at most 8 * 2^32 bits of length:
- 34359738368 bits
- 4294967296 Bytes
## Key
**MUST** be a `String`
## Value
It's up to the Application to decide whether the value is
a string or another type of datum
```
+-- 64 - bits--------------------------+----------------------------------------+
| Key-Length 32 | Value-Length 32 |
+--------------------------------------+----------------------------------------+
\ Key /
|-----------------------------------------------------------------------------|
/ Value \
+-------------------------------------------------------------------------------+
# Message Structure
## Possible Improvements
As for now, we are not having a max abount of bytes the message may have,
so we are relying on the ability of the receiver to dynamically allocate a buffer for the message.
However, we could add a field to tell a PRIORI the length of the whole message.
Probably we would use between 8 B or 24 B to put this info
(This won't be a 2.0 version, as this is not a final document yet)
```
+-+ 64 - bits---+----------------+-------------+----------------+-----------------------+
|0| Version 7 | Message Type 8 | Dev Type 8 | RESERVED 16 | Sign Type 32 |
+-+-------------+----------------+-------------+----------------+-----------------------+
| Timestamp 64 |
+---------------------------------------------------------------------------------------+
| DevID 128 bits |
| |
+---------------------------------------------------------------------------------------+
| Location 192 bits |
| |
| |
+---------------------------------------------------------------------------------------+
\ /
| Fields -----------------------------------------------------------------------------|
/ \
+---------------------------------------------------------------------------------------+
| 0 Padding 64 - n |
+---------------------------------------------------------------------------------------+
| Signature up to-512 bits |
| |
| |
| |
| |
| |
| |
| |
+---------------------------------------------------------------------------------------+
```
# Fields
each field can be at most 8 * 2^32 bits of length:
- 34359738368 bits
- 4294967296 Bytes
## Key
**MUST** be a `String`
## Value
It's up to the Application to decide whether the value is
a string or another type of datum
```
+-- 64 - bits--------------------------+----------------------------------------+
| Key-Length 32 | Value-Length 32 |
+--------------------------------------+----------------------------------------+
\ Key /
|-----------------------------------------------------------------------------|
/ Value \
+-------------------------------------------------------------------------------+
```

View File

@@ -0,0 +1,16 @@
import Foundation
public protocol MessageP {
var version: UInt8 {get}
var messageType: MessageType {get}
var devType: DeviceType {get}
var RESERVED: UInt8 {get}
var signType: SignType {get}
var timestamp: Date {get}
var devID: UInt128 {get}
var location: Location {get}
var fields: [Field] {get}
func toString() -> String
}

View File

@@ -1,43 +1,43 @@
import Foundation
extension UInt8: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt16: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt32: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt64: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt128: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension Date: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
import Foundation
extension UInt8: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt16: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt32: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt64: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension UInt128: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}
extension Date: DataCompatibleP {
public var data: Data {
var obj = self
return Data(bytes: &obj, count: MemoryLayout<Self>.stride)
}
}