-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
252 additions
and
2 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,5 +1,6 @@ | ||
|
||
#include "mode/cbc.h" | ||
#include "mode/pcbc.h" | ||
#include "mode/cfb.h" | ||
#include "mode/ctr.h" | ||
#include "mode/ecb.h" | ||
|
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,99 @@ | ||
|
||
#include "pcbc.h" | ||
#include <cmath> | ||
|
||
namespace cryptian { | ||
|
||
namespace mode { | ||
|
||
namespace pcbc { | ||
|
||
bool Pcbc::isPaddingRequired() { | ||
return true; | ||
} | ||
|
||
std::vector<char> Cipher::transform(const std::vector<char> chunk) { | ||
|
||
const std::size_t blockSize = _algorithm->getBlockSize(); | ||
const std::size_t blocksCount = std::floor(chunk.size() / blockSize); | ||
|
||
std::vector<char> blocks(blockSize * blocksCount); | ||
|
||
char* block = new char[blockSize](); | ||
char* propagation = new char[blockSize](); | ||
|
||
for (size_t i = 0 ; i < blocksCount; i++) { | ||
|
||
size_t offset = i * blockSize; | ||
|
||
std::copy_n(chunk.begin() + offset, blockSize, block); | ||
std::copy_n(chunk.begin() + offset, blockSize, propagation); | ||
|
||
for (size_t j = 0; j < blockSize; j++) { | ||
block[j] ^= _register[j]; | ||
} | ||
|
||
std::vector<char> cipher = _algorithm->encrypt(std::vector<char>(block, block + blockSize)); | ||
|
||
std::copy(cipher.begin(), cipher.end(), blocks.begin() + offset); | ||
|
||
std::copy(cipher.begin(), cipher.end(), _register.begin()); | ||
|
||
for (size_t j = 0; j < blockSize; j++) { | ||
_register[j] ^= propagation[j]; | ||
} | ||
|
||
} | ||
|
||
delete[] block; | ||
delete[] propagation; | ||
|
||
return blocks; | ||
} | ||
|
||
|
||
std::vector<char> Decipher::transform(const std::vector<char> chunk) { | ||
|
||
const std::size_t blockSize = _algorithm->getBlockSize(); | ||
const std::size_t blocksCount = std::floor(chunk.size() / blockSize); | ||
|
||
std::vector<char> blocks(blockSize * blocksCount); | ||
|
||
char* block = new char[blockSize](); | ||
char* propagation = new char[blockSize](); | ||
|
||
for (size_t i = 0 ; i < blocksCount; i++) { | ||
|
||
size_t offset = i * blockSize; | ||
|
||
std::copy_n(chunk.begin() + offset, blockSize, block); | ||
std::copy_n(chunk.begin() + offset, blockSize, propagation); | ||
|
||
std::vector<char> cipher = _algorithm->decrypt(std::vector<char>(block, block + blockSize)); | ||
|
||
for (size_t j = 0; j < blockSize; j++) { | ||
cipher[j] ^= _register[j]; | ||
} | ||
|
||
std::copy(cipher.begin(), cipher.end(), blocks.begin() + offset); | ||
|
||
std::copy(cipher.begin(), cipher.end(), _register.begin()); | ||
|
||
for (size_t j = 0; j < blockSize; j++) { | ||
_register[j] ^= propagation[j]; | ||
} | ||
|
||
} | ||
|
||
delete[] block; | ||
delete[] propagation; | ||
|
||
return blocks; | ||
|
||
} | ||
|
||
}; | ||
|
||
}; | ||
|
||
}; |
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,31 @@ | ||
|
||
#include <mode-base.h> | ||
|
||
namespace cryptian { | ||
|
||
namespace mode { | ||
|
||
namespace pcbc { | ||
|
||
class Pcbc : public cryptian::mode::ModeBase { | ||
public: | ||
bool isPaddingRequired(); | ||
}; | ||
|
||
|
||
class Cipher : public Pcbc { | ||
public: | ||
std::vector<char> transform(const std::vector<char>); | ||
|
||
}; | ||
|
||
class Decipher: public Pcbc { | ||
public: | ||
std::vector<char> transform(const std::vector<char>); | ||
}; | ||
|
||
}; | ||
|
||
}; | ||
|
||
}; |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
|
||
|
||
import {expect} from '@jest/globals'; | ||
|
||
import { randomBytes } from 'crypto'; | ||
import assert from 'assert'; | ||
import cryptian from '../..'; | ||
|
||
const {algorithm: {Dummy}, mode: {pcbc}} = cryptian; | ||
|
||
|
||
(typeof pcbc === 'object' ? describe : describe.skip) ('pcbc', () => { | ||
|
||
const plaintext = Buffer.from('0a4e0adf528e898594699188930c6247493f3c17fce03723e123517d62533c4a', 'hex'); | ||
const ciphertext = Buffer.from('09c31ca738fad69e97e487f0f9783d5c4ab22a6f96946838e2ae470508276351', 'hex'); | ||
|
||
const iv = Buffer.from('038d16786a745f1b', 'hex'); | ||
const dummy = new Dummy(); | ||
|
||
|
||
describe('cipher', () => { | ||
|
||
it('undivided', () => { | ||
const cipher = new pcbc.Cipher(dummy, iv); | ||
|
||
assert(ciphertext.equals(cipher.transform(plaintext)), 'transformed plaintext should be equal to ciphertext'); | ||
}); | ||
|
||
it('divided', () => { | ||
const cipher = new pcbc.Cipher(dummy, iv); | ||
const part = Buffer.concat([ | ||
cipher.transform(plaintext.slice(0, 8)), | ||
cipher.transform(plaintext.slice(8)) | ||
]); | ||
|
||
assert(ciphertext.equals(part), 'transformed plaintext should be equal to ciphertext'); | ||
}); | ||
|
||
describe('throw padding exception', () => { | ||
|
||
it('getBlockSize', () => { | ||
const cipher = new pcbc.Cipher(dummy, iv); | ||
assert.equal(cipher.getBlockSize(), dummy.getBlockSize(), 'cipher.getBlockSize() should equal algorithm.getBlockSize()'); | ||
}); | ||
|
||
it('transform using 5 bytes', () => { | ||
const cipher = new pcbc.Cipher(dummy, iv); | ||
|
||
expect(() => cipher.transform(randomBytes(5))) | ||
.toThrowError('Data size should be aligned to algorithm block size.'); | ||
|
||
}); | ||
|
||
it('transform using 12 bytes', () => { | ||
|
||
const cipher = new pcbc.Cipher(dummy, iv); | ||
|
||
expect(() => cipher.transform(randomBytes(12))) | ||
.toThrowError('Data size should be aligned to algorithm block size.'); | ||
|
||
}); | ||
|
||
}); | ||
|
||
}); | ||
|
||
|
||
describe('decipher', () => { | ||
|
||
|
||
it('undivided', () => { | ||
const decipher = new pcbc.Decipher(dummy, iv); | ||
|
||
assert(plaintext.equals(decipher.transform(ciphertext)), 'transformed ciphertext should be equal to plaintext'); | ||
}); | ||
|
||
|
||
it('divided', () => { | ||
const decipher = new pcbc.Decipher(dummy, iv); | ||
const part = Buffer.concat([ | ||
decipher.transform(ciphertext.slice(0, 8)), | ||
decipher.transform(ciphertext.slice(8)) | ||
]); | ||
|
||
assert(plaintext.equals(part), 'transformed ciphertext should be equal to plaintext'); | ||
}); | ||
|
||
|
||
describe('throw padding exception', () => { | ||
|
||
it('getBlockSize', () => { | ||
const decipher = new pcbc.Decipher(dummy, iv); | ||
assert.equal(decipher.getBlockSize(), dummy.getBlockSize(), 'decipher.getBlockSize() should equal algorithm.getBlockSize()'); | ||
}); | ||
|
||
|
||
it('transform using 5 bytes', () => { | ||
const decipher = new pcbc.Decipher(dummy, iv); | ||
|
||
expect(() => decipher.transform(randomBytes(5))).toThrowError('Data size should be aligned to algorithm block size.'); | ||
|
||
}); | ||
|
||
|
||
it('transform using 12 bytes', () => { | ||
const decipher = new pcbc.Decipher(dummy, iv); | ||
|
||
expect(() => decipher.transform(randomBytes(12))).toThrowError('Data size should be aligned to algorithm block size.'); | ||
}); | ||
|
||
}); | ||
|
||
}); | ||
|
||
}); |