Skip to content

Commit

Permalink
Merge pull request krzyzanowskim#887 from NathanFallet/rsa
Browse files Browse the repository at this point in the history
RSA
  • Loading branch information
krzyzanowskim authored Mar 10, 2022
2 parents f2d214f + 14e3c3e commit 7bfec73
Show file tree
Hide file tree
Showing 27 changed files with 3,659 additions and 0 deletions.
108 changes: 108 additions & 0 deletions CryptoSwift.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,33 @@ let encrypt = try AEADChaCha20Poly1305.encrypt(plaintext, key: key, iv: nonce, a
let decrypt = try AEADChaCha20Poly1305.decrypt(ciphertext, key: key, iv: nonce, authenticationHeader: header, authenticationTag: tagArr: tag)
```

##### RSA

RSA initialization from parameters

```swift
let input: Array<UInt8> = [0,1,2,3,4,5,6,7,8,9]

let n: Array<UInt8> = // RSA modulus
let e: Array<UInt8> = // RSA public exponent
let d: Array<UInt8> = // RSA private exponent

let rsa = RSA(n: n, e: e, d: d)

do {
let encrypted = try rsa.encrypt(input)
let decrypted = try rsa.decrypt(encrypted)
} catch {
print(error)
}
```

RSA key generation

```swift
let rsa = RSA(keySize: 2048) // This generates a modulus, public exponent and private exponent with the given size
```

## Author

CryptoSwift is owned and maintained by [Marcin Krzyżanowski](http://www.krzyzanowskim.com)
Expand Down
5 changes: 5 additions & 0 deletions Sources/CryptoSwift/Array+Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ extension Array {
var slice: ArraySlice<Element> {
self[self.startIndex ..< self.endIndex]
}

@inlinable
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}

extension Array where Element == UInt8 {
Expand Down
126 changes: 126 additions & 0 deletions Sources/CryptoSwift/BigInt/Addition.swift
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
}
}

74 changes: 74 additions & 0 deletions Sources/CryptoSwift/BigInt/BigInt.swift
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
}
}
}
Loading

0 comments on commit 7bfec73

Please sign in to comment.