This repository has been archived by the owner on Dec 12, 2024. It is now read-only.
generated from TBD54566975/tbd-project-template
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
441 additions
and
278 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import XCTest | ||
|
||
/// Representation of a test vector | ||
/// | ||
/// This representation uses the following generics: | ||
/// - Input: Type of the file's vector object `input` property. This is unique for each test vector file, and should | ||
/// be defined in the vector's README file. | ||
/// - Output: Type of the file's vector object `output` property. This is unique for each test vector file, and should | ||
/// be defined in the vector's README file. | ||
/// | ||
/// [Specification Reference](https://github.com/TBD54566975/sdk-development/tree/main/web5-test-vectors) | ||
struct TestVector<Input: Codable, Output: Codable>: Codable { | ||
|
||
/// A general description of the test vectors collection. | ||
private let description: String | ||
|
||
/// An array of test vector objects. | ||
private let vectors: [Vector] | ||
|
||
/// Default Initializer | ||
/// - Parameters: | ||
/// - fileName: Name of the JSON file containing the test vectors. | ||
/// - subdirectory: Name of subdirectory that contains `fileName`. Used to disambiguate when there are multiple | ||
/// test vector files with the same name. | ||
init( | ||
fileName: String, | ||
subdirectory: String? = nil | ||
) throws { | ||
guard | ||
let url = Bundle.module.url( | ||
forResource: fileName, | ||
withExtension: "json", | ||
subdirectory: subdirectory | ||
) | ||
else { | ||
fatalError("Missing file: \(fileName).json") | ||
} | ||
|
||
let data = try Data(contentsOf: url) | ||
self = try JSONDecoder().decode(Self<Input, Output>.self, from: data) | ||
} | ||
|
||
/// Run a test vector, individually executing each vector object defined within it. | ||
/// | ||
/// - Parameters: | ||
/// - vectorHandler: Closure that will be executed with each vector object defined within the test vector file. | ||
/// This is where you write your assertions! | ||
func run( | ||
vectorHandler: (Vector) throws -> Void | ||
) { | ||
XCTContext.runActivity(named: description) { _ in | ||
for vector in vectors { | ||
do { | ||
try XCTContext.runActivity(named: vector.description) { _ in | ||
try vectorHandler(vector) | ||
} | ||
} catch { | ||
XCTFail("Unexpected error: \(error)") | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
extension TestVector { | ||
|
||
/// Representation of individual vector object that appears within a test vector file | ||
/// | ||
/// [Specification Reference](https://github.com/TBD54566975/sdk-development/tree/main/web5-test-vectors) | ||
struct Vector: Codable { | ||
|
||
/// A description of what this test vector is testing. | ||
let description: String | ||
|
||
/// The input for the test vector, which can be of any type. | ||
let input: Input | ||
|
||
/// The expected output for the test vector, which can be of any type. | ||
let output: Output | ||
|
||
/// Indicates whether the test vector is expected to produce an error. | ||
let errors: Bool? | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import CustomDump | ||
import TestUtilities | ||
import XCTest | ||
|
||
@testable import tbDEX | ||
|
||
final class Web5TestVectorsEd25519: XCTestCase { | ||
|
||
func test_bytesToPrivateKey() throws { | ||
/// Input data format for `bytes-to-private-key` test vectors | ||
struct Input: Codable { | ||
let privateKeyBytes: String | ||
} | ||
|
||
let testVector = try TestVector<Input, Jwk>( | ||
fileName: "bytes-to-private-key", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let privateKeyBytes = try XCTUnwrap(Data.fromHexString(vector.input.privateKeyBytes)) | ||
let privateKey = try Ed25519.shared.bytesToPrivateKey(privateKeyBytes) | ||
XCTAssertNoDifference(privateKey, vector.output) | ||
} | ||
} | ||
|
||
func test_bytesToPublicKey() throws { | ||
/// Input data format for `bytes-to-public-key` test vectors | ||
struct Input: Codable { | ||
let publicKeyBytes: String | ||
} | ||
|
||
let testVector = try TestVector<Input, Jwk>( | ||
fileName: "bytes-to-public-key", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let publicKeyBytes = try XCTUnwrap(Data.fromHexString(vector.input.publicKeyBytes)) | ||
let publicKey = try Ed25519.shared.bytesToPublicKey(publicKeyBytes) | ||
XCTAssertNoDifference(publicKey, vector.output) | ||
} | ||
} | ||
|
||
func test_computePublicKey() throws { | ||
/// Input data format for `compute-public-key` test vectors | ||
struct Input: Codable { | ||
let privateKey: Jwk | ||
} | ||
|
||
let testVector = try TestVector<Input, Jwk>( | ||
fileName: "compute-public-key", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let publicKey = try Ed25519.shared.computePublicKey(privateKey: vector.input.privateKey) | ||
XCTAssertNoDifference(publicKey, vector.output) | ||
} | ||
} | ||
|
||
func test_privateKeyToBytes() throws { | ||
/// Input data format for `private-key-to-bytes` test vectors | ||
struct Input: Codable { | ||
let privateKey: Jwk | ||
} | ||
|
||
let testVector = try TestVector<Input, String>( | ||
fileName: "private-key-to-bytes", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let privateKeyBytes = try Ed25519.shared.privateKeyToBytes(vector.input.privateKey) | ||
XCTAssertNoDifference(privateKeyBytes, try XCTUnwrap(Data.fromHexString(vector.output))) | ||
} | ||
} | ||
|
||
func test_publicKeyToBytes() throws { | ||
/// Input data format for `public-key-to-bytes` test vectors | ||
struct Input: Codable { | ||
let publicKey: Jwk | ||
} | ||
|
||
let testVector = try TestVector<Input, String>( | ||
fileName: "public-key-to-bytes", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let publicKeyBytes = try Ed25519.shared.publicKeyToBytes(vector.input.publicKey) | ||
XCTAssertNoDifference(publicKeyBytes, try XCTUnwrap(Data.fromHexString(vector.output))) | ||
} | ||
} | ||
|
||
func test_sign() throws { | ||
/// Input data format for `sign` test vectors | ||
struct Input: Codable { | ||
let data: String | ||
let key: Jwk | ||
} | ||
|
||
let testVector = try TestVector<Input, String>( | ||
fileName: "sign", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let signature = try Ed25519.shared.sign( | ||
privateKey: vector.input.key, | ||
payload: try XCTUnwrap(Data.fromHexString(vector.input.data)) | ||
) | ||
|
||
// Apple's Ed25519 implementation employs randomization to generate different signatures | ||
// on every call, even for the same data and key, to guard against side-channel attacks. | ||
// https://developer.apple.com/documentation/cryptokit/curve25519/signing/privatekey/signature(for:) | ||
// | ||
// Because of this, the signature we just generated will NOT be the same as the vector's output, | ||
// but both will be valid signatures. | ||
let isVectorOutputSignatureValid = try Ed25519.shared.verify( | ||
publicKey: try Ed25519.shared.computePublicKey(privateKey: vector.input.key), | ||
signature: try XCTUnwrap(Data.fromHexString(vector.output)), | ||
signedPayload: try XCTUnwrap(Data.fromHexString(vector.input.data)) | ||
) | ||
|
||
let isGeneratedSignatureValid = try Ed25519.shared.verify( | ||
publicKey: try Ed25519.shared.computePublicKey(privateKey: vector.input.key), | ||
signature: signature, | ||
signedPayload: try XCTUnwrap(Data.fromHexString(vector.input.data)) | ||
) | ||
|
||
XCTAssertTrue(isVectorOutputSignatureValid) | ||
XCTAssertTrue(isGeneratedSignatureValid) | ||
XCTAssertNotEqual(signature.toHexString(), vector.output) | ||
} | ||
} | ||
|
||
func test_verify() throws { | ||
/// Input data format for `verify` test vectors | ||
struct Input: Codable { | ||
let data: String | ||
let key: Jwk | ||
let signature: String | ||
} | ||
|
||
let testVector = try TestVector<Input, Bool>( | ||
fileName: "verify", | ||
subdirectory: "ed25519" | ||
) | ||
|
||
testVector.run { vector in | ||
let isValid = try Ed25519.shared.verify( | ||
publicKey: vector.input.key, | ||
signature: try XCTUnwrap(Data.fromHexString(vector.input.signature)), | ||
signedPayload: try XCTUnwrap(Data.fromHexString(vector.input.data)) | ||
) | ||
XCTAssertNoDifference(isValid, vector.output) | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.