Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChaCha20 Explicitly Set Counter #1010

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions Sources/CryptoSwift/ChaCha20.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public final class ChaCha20: BlockCipher {
fileprivate let key: Key
fileprivate var counter: Array<UInt8>

public init(key: Array<UInt8>, iv nonce: Array<UInt8>) throws {
precondition(nonce.count == 12 || nonce.count == 8)
public init(key: Array<UInt8>, counter: Array<UInt8> = [0, 0, 0, 0], iv nonce: Array<UInt8>) throws {
precondition(counter.count == 4 && (nonce.count == 12 || nonce.count == 8))

if key.count != 32 {
throw Error.invalidKeyOrInitializationVector
Expand All @@ -39,9 +39,11 @@ public final class ChaCha20: BlockCipher {
self.keySize = self.key.count

if nonce.count == 8 {
self.counter = [0, 0, 0, 0, 0, 0, 0, 0] + nonce
self.counter = counter + [0, 0, 0, 0] + nonce
} else if nonce.count == 12 {
self.counter = counter + nonce
} else {
self.counter = [0, 0, 0, 0] + nonce
throw Error.invalidKeyOrInitializationVector
}

assert(self.counter.count == 16)
Expand Down
34 changes: 33 additions & 1 deletion Tests/CryptoSwiftTests/ChaCha20Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ final class ChaCha20Tests: XCTestCase {
XCTFail()
}
}

/// Test Vector - https://datatracker.ietf.org/doc/html/rfc9001#name-chacha20-poly1305-short-hea
func testChaCha20ExplicitCounterV1() {
let hpKey = Array(hex: "0x25a282b9e82f06f21f488917a4fc8f1b73573685608597d0efcb076b0ab7a7a4")
/// Sample = 0x5e5cd55c41f69080575d7999c25a5bfb
let counter = Array(hex: "0x5e5cd55c")
let iv = Array(hex: "0x41f69080575d7999c25a5bfb")

do {
let mask = try CryptoSwift.ChaCha20(key: hpKey, counter: counter, iv: iv).encrypt(Array<UInt8>(repeating: 0, count: 5))
XCTAssertEqual(mask, Array(hex: "0xaefefe7d03"))
} catch {
XCTFail("\(error)")
}
}

/// Test Vector - https://www.ietf.org/archive/id/draft-ietf-quic-v2-10.html#name-chacha20-poly1305-short-head
func testChaCha20ExplicitCounterV2() {
let hpKey = Array(hex: "0xd659760d2ba434a226fd37b35c69e2da8211d10c4f12538787d65645d5d1b8e2")
/// Sample = 0xe7b6b932bc27d786f4bc2bb20f2162ba
let counter = Array(hex: "0xe7b6b932")
let iv = Array(hex: "0xbc27d786f4bc2bb20f2162ba")

do {
let mask = try CryptoSwift.ChaCha20(key: hpKey, counter: counter, iv: iv).encrypt(Array<UInt8>(repeating: 0, count: 5))
XCTAssertEqual(mask, Array(hex: "0x97580e32bf"))
} catch {
XCTFail("\(error)")
}
}
}

extension ChaCha20Tests {
Expand All @@ -114,7 +144,9 @@ extension ChaCha20Tests {
("testChaCha20", testChaCha20),
("testCore", testCore),
("testVector1Py", testVector1Py),
("testChaCha20EncryptPartial", testChaCha20EncryptPartial)
("testChaCha20EncryptPartial", testChaCha20EncryptPartial),
("testChaCha20ExplicitCounterV1", testChaCha20ExplicitCounterV1),
("testChaCha20ExplicitCounterV2", testChaCha20ExplicitCounterV2)
]

return tests
Expand Down