102 lines
3.2 KiB
Swift
102 lines
3.2 KiB
Swift
//
|
|
// Copyright Amazon.com Inc. or its affiliates.
|
|
// All Rights Reserved.
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
import Foundation
|
|
import libtommathAmplify
|
|
|
|
public final class AmplifyBigInt {
|
|
|
|
var value = amplify_mp_int(used: 0, alloc: 0, sign: AMPLIFY_MP_ZPOS, dp: nil)
|
|
|
|
public init() {
|
|
|
|
}
|
|
|
|
public init?(_ numericString: String, radix: Int = 10) {
|
|
if radix < 2 || radix > 36 {
|
|
print("Error in creating BigInt, radix is out of range")
|
|
return nil
|
|
}
|
|
let uppercasedValue = numericString.uppercased()
|
|
let cString = uppercasedValue.cString(using: .utf8)
|
|
let error = amplify_mp_read_radix(&value, cString, Int32(radix))
|
|
if error != AMPLIFY_MP_OKAY {
|
|
print("Error in creating BigInt - \(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public convenience init?(_ numericString: String) {
|
|
self.init(numericString, radix: 10)
|
|
}
|
|
|
|
/// Creates a signed big integer from the bytes provided
|
|
///
|
|
/// The first byte determine the sign of the number, if the first byte is
|
|
/// 0 == positive or 1 == negative.
|
|
/// - Parameter data: bytes to represent as signed number
|
|
public init(_ data: [UInt8]) {
|
|
let error = amplify_mp_from_sbin(&value, data, data.count)
|
|
guard error == AMPLIFY_MP_OKAY else {
|
|
fatalError("Could not create a signed number from data - \(error)")
|
|
}
|
|
}
|
|
|
|
/// Creates a un-signed big integer from the bytes provided
|
|
///
|
|
/// - Parameter data: bytes to represent as un-signed number
|
|
public init(unsignedData data: [UInt8]) {
|
|
let error = amplify_mp_from_ubin(&value, data, data.count)
|
|
guard error == AMPLIFY_MP_OKAY else {
|
|
fatalError("Could not create a signed number from data - \(error)")
|
|
}
|
|
}
|
|
|
|
public required convenience init(integerLiteral value: IntegerLiteralType) {
|
|
self.init(value)
|
|
}
|
|
|
|
public convenience init(_ int: Int) {
|
|
self.init("\(int)")!
|
|
}
|
|
|
|
deinit {
|
|
amplify_mp_clear(&value)
|
|
}
|
|
|
|
public var asString: String {
|
|
return self.asString(radix: 10)
|
|
}
|
|
|
|
public func asString(radix: Int = 10) -> String {
|
|
// Will be replaced with this method - https://developer.apple.com/documentation/swift/string/2997127-init
|
|
// when moving to `BinaryInteger` conformance.
|
|
if radix < 2 || radix > 36 {
|
|
fatalError("Could not convert to string, radix is out of range")
|
|
}
|
|
var stringLength = Int32()
|
|
let lengthResult = amplify_mp_radix_size(&value, Int32(radix), &stringLength)
|
|
guard lengthResult == AMPLIFY_MP_OKAY else {
|
|
fatalError("Could not find the size of the string to represent - \(lengthResult)")
|
|
}
|
|
let stringLengthInt = Int(stringLength)
|
|
var cString = [Int8](repeating: 0, count: stringLengthInt)
|
|
var written = size_t()
|
|
let conversionResult = amplify_mp_to_radix(&value, &cString, stringLengthInt, &written, Int32(radix))
|
|
guard conversionResult == AMPLIFY_MP_OKAY else {
|
|
fatalError("Could not convert to string - \(conversionResult)")
|
|
}
|
|
|
|
return String(cString: cString)
|
|
}
|
|
}
|
|
|
|
enum AmplifyBigIntError: Error {
|
|
|
|
case conversion(amplify_mp_err)
|
|
}
|