Skip to content

Commit

Permalink
Implement sign and verify for ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
qtbeee committed Sep 27, 2019
1 parent 7564cfa commit 33637cf
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 7 deletions.
21 changes: 14 additions & 7 deletions Sources/Hedera/Transaction.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import SwiftProtobuf
import Sodium
import Foundation

// TODO: this should probably be its own file, and possibly an enum instead
struct HederaError: Error {}

public struct Transaction {
let inner: Proto_Transaction
var inner: Proto_Transaction

init(_ tx: Proto_Transaction) {
inner = tx
Expand All @@ -15,19 +16,26 @@ public struct Transaction {
Bytes(inner.bodyBytes)
}

public func sign(with key: Ed25519PrivateKey) throws -> Self {
// TODO: definitely test this function to make sure this works as it should
public mutating func sign(with key: Ed25519PrivateKey) throws -> Self {
if !inner.hasSigMap { inner.sigMap = Proto_SignatureMap() }

let pubKey = key.publicKey.bytes
let sigMap = inner.sigMap

if sigMap.sigPair.contains(where: { (sig) in
if inner.sigMap.sigPair.contains(where: { (sig) in
let pubKeyPrefix = sig.pubKeyPrefix
return pubKey.starts(with: pubKeyPrefix)
}) {
// Transaction was already signed with this key!
throw HederaError()
}

// TODO: write the rest of the function
// TODO: private key needs to hold onto keypair from sodium
let sig = key.sign(message: Bytes(inner.bodyBytes))
var sigPair = Proto_SignaturePair()
sigPair.pubKeyPrefix = Data(pubKey)
sigPair.ed25519 = Data(sig)

inner.sigMap.sigPair.append(sigPair)

return self
}
Expand All @@ -39,5 +47,4 @@ extension Transaction: ProtoConvertible {
}
}

// TODO: Add #sign -> Self
// TODO: Add #execute -> TransactionId
4 changes: 4 additions & 0 deletions Sources/Hedera/crypto/ed25519/Ed25519PrivateKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public struct Ed25519PrivateKey {
public var publicKey: Ed25519PublicKey {
Ed25519PublicKey(bytes: inner.publicKey)!
}

func sign(message bytes: Bytes) -> Bytes {
sodium.sign.signature(message: bytes, secretKey: inner.secretKey)!
}
}

extension Ed25519PrivateKey: CustomStringConvertible, CustomDebugStringConvertible {
Expand Down
4 changes: 4 additions & 0 deletions Sources/Hedera/crypto/ed25519/Ed25519PublicKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public struct Ed25519PublicKey {
var bytes: Bytes {
inner
}

func verify(signature: Bytes, of message: Bytes) -> Bool {
sodium.sign.verify(message: message, publicKey: inner, signature: signature)
}
}

extension Ed25519PublicKey: CustomStringConvertible, CustomDebugStringConvertible {
Expand Down
11 changes: 11 additions & 0 deletions Tests/HederaTests/crypto/ed25519/Ed25519PrivateKeyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ let combinedKeyBytes = Array<UInt8>(arrayLiteral: 219, 72, 75, 130, 142, 100, 17

//let testKeyPem = "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEINtIS4KOZLLY8SzjwKDpOguMznrxu485yXcyOUSCU44Q\n-----END PRIVATE KEY-----\n"

let message = "This is a message about the world."
let signature = "73bea53f31ca9c42a422ecb7516ec08d0bbd1a6bfd630ccf10ec1872454814d29f4a8011129cd007eab544af01a75f508285b591e5bed24b68f927751e49e30e"

final class Ed25519PrivateKeyTests: XCTestCase {
func testGenerate() {
XCTAssertNoThrow(Ed25519PrivateKey())
Expand Down Expand Up @@ -61,6 +64,13 @@ final class Ed25519PrivateKeyTests: XCTestCase {
XCTAssertEqual(String(publicFromPrivate), String(publicKey))
}

func testSign() {
let key = Ed25519PrivateKey(privateKeyString)!
let sig = key.sign(message: message.bytes)

XCTAssertEqual(hexEncode(bytes: sig), signature)
}

static var allTests = [
("testGenerate", testGenerate),
("testFromBytes", testFromBytes),
Expand All @@ -69,5 +79,6 @@ final class Ed25519PrivateKeyTests: XCTestCase {
("testFromRawString", testFromRawString),
("testFromBadString", testFromBadString),
("testGetPublicKey", testGetPublicKey),
("testSign", testSign),
]
}
7 changes: 7 additions & 0 deletions Tests/HederaTests/crypto/ed25519/Ed25519PublicKeyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,19 @@ final class Ed25519PublicKeyTests: XCTestCase {
XCTAssertEqual(String(key!), publicKeyString)
}

func testVerify() {
let key = Ed25519PublicKey(publicKeyString)!
let verified = key.verify(signature: try! hexDecode(signature), of: message.bytes)
XCTAssertTrue(verified)
}

static var allTests = [
("testFromBytes", testFromBytes),
("testFromBadBytes", testFromBadBytes),
("testFromString", testFromString),
("testFromRawString", testFromRawString),
("testFromBadString", testFromBadString),
("testToString", testToString),
("testVerify", testVerify),
]
}

0 comments on commit 33637cf

Please sign in to comment.