forked from krzyzanowskim/CryptoSwift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request krzyzanowskim#887 from NathanFallet/rsa
RSA
- Loading branch information
Showing
27 changed files
with
3,659 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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,126 @@ | ||
// | ||
// Addition.swift | ||
// BigInt | ||
// | ||
// Created by Károly Lőrentey on 2016-01-03. | ||
// Copyright © 2016-2017 Károly Lőrentey. | ||
// | ||
|
||
extension BigUInt { | ||
//MARK: Addition | ||
|
||
/// Add `word` to this integer in place. | ||
/// `word` is shifted `shift` words to the left before being added. | ||
/// | ||
/// - Complexity: O(max(count, shift)) | ||
internal mutating func addWord(_ word: Word, shiftedBy shift: Int = 0) { | ||
precondition(shift >= 0) | ||
var carry = word | ||
var i = shift | ||
while carry > 0 { | ||
let (d, c) = self[i].addingReportingOverflow(carry) | ||
self[i] = d | ||
carry = (c ? 1 : 0) | ||
i += 1 | ||
} | ||
} | ||
|
||
/// Add the digit `d` to this integer and return the result. | ||
/// `d` is shifted `shift` words to the left before being added. | ||
/// | ||
/// - Complexity: O(max(count, shift)) | ||
internal func addingWord(_ word: Word, shiftedBy shift: Int = 0) -> BigUInt { | ||
var r = self | ||
r.addWord(word, shiftedBy: shift) | ||
return r | ||
} | ||
|
||
/// Add `b` to this integer in place. | ||
/// `b` is shifted `shift` words to the left before being added. | ||
/// | ||
/// - Complexity: O(max(count, b.count + shift)) | ||
internal mutating func add(_ b: BigUInt, shiftedBy shift: Int = 0) { | ||
precondition(shift >= 0) | ||
var carry = false | ||
var bi = 0 | ||
let bc = b.count | ||
while bi < bc || carry { | ||
let ai = shift + bi | ||
let (d, c) = self[ai].addingReportingOverflow(b[bi]) | ||
if carry { | ||
let (d2, c2) = d.addingReportingOverflow(1) | ||
self[ai] = d2 | ||
carry = c || c2 | ||
} | ||
else { | ||
self[ai] = d | ||
carry = c | ||
} | ||
bi += 1 | ||
} | ||
} | ||
|
||
/// Add `b` to this integer and return the result. | ||
/// `b` is shifted `shift` words to the left before being added. | ||
/// | ||
/// - Complexity: O(max(count, b.count + shift)) | ||
internal func adding(_ b: BigUInt, shiftedBy shift: Int = 0) -> BigUInt { | ||
var r = self | ||
r.add(b, shiftedBy: shift) | ||
return r | ||
} | ||
|
||
/// Increment this integer by one. If `shift` is non-zero, it selects | ||
/// the word that is to be incremented. | ||
/// | ||
/// - Complexity: O(count + shift) | ||
internal mutating func increment(shiftedBy shift: Int = 0) { | ||
self.addWord(1, shiftedBy: shift) | ||
} | ||
|
||
/// Add `a` and `b` together and return the result. | ||
/// | ||
/// - Complexity: O(max(a.count, b.count)) | ||
public static func +(a: BigUInt, b: BigUInt) -> BigUInt { | ||
return a.adding(b) | ||
} | ||
|
||
/// Add `a` and `b` together, and store the sum in `a`. | ||
/// | ||
/// - Complexity: O(max(a.count, b.count)) | ||
public static func +=(a: inout BigUInt, b: BigUInt) { | ||
a.add(b, shiftedBy: 0) | ||
} | ||
} | ||
|
||
extension BigInt { | ||
/// Add `a` to `b` and return the result. | ||
public static func +(a: BigInt, b: BigInt) -> BigInt { | ||
switch (a.sign, b.sign) { | ||
case (.plus, .plus): | ||
return BigInt(sign: .plus, magnitude: a.magnitude + b.magnitude) | ||
case (.minus, .minus): | ||
return BigInt(sign: .minus, magnitude: a.magnitude + b.magnitude) | ||
case (.plus, .minus): | ||
if a.magnitude >= b.magnitude { | ||
return BigInt(sign: .plus, magnitude: a.magnitude - b.magnitude) | ||
} | ||
else { | ||
return BigInt(sign: .minus, magnitude: b.magnitude - a.magnitude) | ||
} | ||
case (.minus, .plus): | ||
if b.magnitude >= a.magnitude { | ||
return BigInt(sign: .plus, magnitude: b.magnitude - a.magnitude) | ||
} | ||
else { | ||
return BigInt(sign: .minus, magnitude: a.magnitude - b.magnitude) | ||
} | ||
} | ||
} | ||
|
||
/// Add `b` to `a` in place. | ||
public static func +=(a: inout BigInt, b: BigInt) { | ||
a = a + b | ||
} | ||
} | ||
|
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,74 @@ | ||
// | ||
// BigInt.swift | ||
// BigInt | ||
// | ||
// Created by Károly Lőrentey on 2015-12-27. | ||
// Copyright © 2016-2017 Károly Lőrentey. | ||
// | ||
|
||
//MARK: BigInt | ||
|
||
/// An arbitary precision signed integer type, also known as a "big integer". | ||
/// | ||
/// Operations on big integers never overflow, but they might take a long time to execute. | ||
/// The amount of memory (and address space) available is the only constraint to the magnitude of these numbers. | ||
/// | ||
/// This particular big integer type uses base-2^64 digits to represent integers. | ||
/// | ||
/// `BigInt` is essentially a tiny wrapper that extends `BigUInt` with a sign bit and provides signed integer | ||
/// operations. Both the underlying absolute value and the negative/positive flag are available as read-write | ||
/// properties. | ||
/// | ||
/// Not all algorithms of `BigUInt` are available for `BigInt` values; for example, there is no square root or | ||
/// primality test for signed integers. When you need to call one of these, just extract the absolute value: | ||
/// | ||
/// ```Swift | ||
/// BigInt(255).abs.isPrime() // Returns false | ||
/// ``` | ||
/// | ||
public struct BigInt: SignedInteger { | ||
public enum Sign { | ||
case plus | ||
case minus | ||
} | ||
|
||
public typealias Magnitude = BigUInt | ||
|
||
/// The type representing a digit in `BigInt`'s underlying number system. | ||
public typealias Word = BigUInt.Word | ||
|
||
public static var isSigned: Bool { | ||
return true | ||
} | ||
|
||
/// The absolute value of this integer. | ||
public var magnitude: BigUInt | ||
|
||
/// True iff the value of this integer is negative. | ||
public var sign: Sign | ||
|
||
/// Initializes a new big integer with the provided absolute number and sign flag. | ||
public init(sign: Sign, magnitude: BigUInt) { | ||
self.sign = (magnitude.isZero ? .plus : sign) | ||
self.magnitude = magnitude | ||
} | ||
|
||
/// Return true iff this integer is zero. | ||
/// | ||
/// - Complexity: O(1) | ||
public var isZero: Bool { | ||
return magnitude.isZero | ||
} | ||
|
||
/// Returns `-1` if this value is negative and `1` if it’s positive; otherwise, `0`. | ||
/// | ||
/// - Returns: The sign of this number, expressed as an integer of the same type. | ||
public func signum() -> BigInt { | ||
switch sign { | ||
case .plus: | ||
return isZero ? 0 : 1 | ||
case .minus: | ||
return -1 | ||
} | ||
} | ||
} |
Oops, something went wrong.