Skip to content

Commit

Permalink
added: SodiumRandomNumberGenerator (jedisct1#255)
Browse files Browse the repository at this point in the history
* added: SodiumRandomNumberGenerator

* fixed: Test

* refactored
  • Loading branch information
c128128 authored May 27, 2022
1 parent 862e9ad commit 54d520e
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,16 @@ let seed = "0123456789abcdef0123456789abcdef".bytes
let stream = sodium.randomBytes.deterministic(length: 1000, seed: seed)!
```

Use `RandomBytes.Generator` as a generator to produce cryptographically secure pseudorandom numbers.

```swift
var rng = RandomBytes.Generator()
let randomUInt32 = UInt32.random(in: 0...10, using: &rng)
let randomUInt64 = UInt64.random(in: 0...10, using: &rng)
let randomInt = Int.random(in: 0...10, using: &rng)
let randomDouble = Double.random(in: 0...1, using: &rng)
```

## Password hashing

Password hashing provides the ability to derive key material from a low-entropy password. Password hashing functions are designed to be expensive to hamper brute force attacks, thus the computational and memory parameters may be user-defined.
Expand Down
18 changes: 18 additions & 0 deletions Sodium/RandomBytes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,21 @@ extension RandomBytes {
return output
}
}

extension RandomBytes {
public struct Generator: RandomNumberGenerator {
private let sodium = Sodium()

public init() {}

public mutating func next() -> UInt64 {
guard let bytes = self.sodium.randomBytes.buf(length: MemoryLayout<UInt64>.size) else {
fatalError("Sodium Random Number Generator is broken")
}

return bytes.withUnsafeBytes { pointer in
return pointer.load(as: UInt64.self)
}
}
}
}
11 changes: 11 additions & 0 deletions Tests/SodiumTests/ReadmeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ class ReadmeTests : XCTestCase {
let randomData = sodium.randomBytes.buf(length: 1000)

XCTAssertNotNil(randomData)

var rng = RandomBytes.Generator()
let randomUInt32 = UInt32.random(in: 0...10, using: &rng)
let randomUInt64 = UInt64.random(in: 0...10, using: &rng)
let randomInt = Int.random(in: 0...10, using: &rng)
let randomDouble = Double.random(in: 0...1, using: &rng)

XCTAssert(randomUInt32 >= 0 && randomUInt32 <= 10)
XCTAssert(randomUInt64 >= 0 && randomUInt64 <= 10)
XCTAssert(randomInt >= 0 && randomInt <= 10)
XCTAssert(randomDouble >= 0 && randomDouble <= 1)
}

func testPasswordHashing() {
Expand Down
10 changes: 10 additions & 0 deletions Tests/SodiumTests/SodiumTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,16 @@ class SodiumTests: XCTestCase {
let seed = sodium.utils.hex2bin("00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff", ignore: " ")!
let randomd = sodium.utils.bin2hex(sodium.randomBytes.deterministic(length: 10, seed: seed)!)!
XCTAssertEqual(randomd, "444dc0602207c270b93f")

var c3 = 0
var rng = RandomBytes.Generator()
let ref3 = UInt32.random(in: 0...UInt32.max, using: &rng)
for _ in (0..<100) {
if UInt32.random(in: 0...UInt32.max, using: &rng) == ref3 {
c3 += 1
}
}
XCTAssert(c3 < 10)
}

func testShortHash() {
Expand Down

0 comments on commit 54d520e

Please sign in to comment.