All checks were successful
continuous-integration/drone/push Build is passing
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { MEMBER_MASK, NB_ROUNDS, TWEAK_LENGTH, PT, LFSR_8_TK2, LFSR_8_TK3, S8, C } from './constants'
|
|
|
|
/**
|
|
* Create a tweakey based on the specified domain separation, nonce, key and current counter state.
|
|
* @param counter The counter.
|
|
* @param domainSeparation The domain separation.
|
|
* @param nonce The nonce.
|
|
* @param key The encryption key.
|
|
* @returns The tweakey.
|
|
*/
|
|
export function tweakeyEncode (counter: number[], domainSeparation: number, nonce: number[], key: number[]): number[] {
|
|
return counter.concat([domainSeparation ^ MEMBER_MASK], Array(8).fill(0), nonce, key)
|
|
}
|
|
|
|
/**
|
|
* Perform a round of SKINNY-188/384+ encryption.
|
|
* @param plaintext The plaintext to encrypt.
|
|
* @param tweakey The tweakey to use for encryption.
|
|
* @returns The ciphertext.
|
|
*/
|
|
export function skinnyEncrypt (plaintext: number[], tweakey: number[]): number[] {
|
|
const tk = Array(NB_ROUNDS + 1).fill(Array(TWEAK_LENGTH).fill(0))
|
|
|
|
tk[0] = [...Array(TWEAK_LENGTH).keys()].map(i => tweakey[i])
|
|
|
|
for (let i = 0; i < NB_ROUNDS - 1; i++) {
|
|
tk[i + 1] = [...tk[i]]
|
|
|
|
for (let j = 0; j < TWEAK_LENGTH; j++) {
|
|
tk[i + 1][j] = tk[i][j - j % 16 + PT[j % 16]]
|
|
}
|
|
|
|
for (let j = 0; j < 8; j++) {
|
|
tk[i + 1][j + 16] = LFSR_8_TK2[tk[i + 1][j + 16]]
|
|
tk[i + 1][j + 32] = LFSR_8_TK3[tk[i + 1][j + 32]]
|
|
}
|
|
}
|
|
|
|
let s = [...Array(16).keys()].map(i => plaintext[i])
|
|
for (let i = 0; i < NB_ROUNDS; i++) {
|
|
for (let j = 0; j < 16; j++) {
|
|
s[j] = S8[s[j]]
|
|
}
|
|
|
|
s[0] ^= (C[i] & 0xf)
|
|
s[4] ^= (C[i] >> 4) & 0xf
|
|
s[8] ^= 0x2
|
|
|
|
for (let j = 0; j < 8; j++) {
|
|
s[j] ^= tk[i][j] ^ tk[i][j + 16] ^ tk[i][j + 32]
|
|
}
|
|
|
|
s = [s[0], s[1], s[2], s[3], s[7], s[4], s[5], s[6], s[10], s[11], s[8], s[9], s[13], s[14], s[15], s[12]]
|
|
|
|
for (let j = 0; j < 4; j++) {
|
|
const tmp = [...s]
|
|
s[j] = tmp[j] ^ tmp[8 + j] ^ tmp[12 + j]
|
|
s[4 + j] = tmp[j]
|
|
s[8 + j] = tmp[4 + j] ^ tmp[8 + j]
|
|
s[12 + j] = tmp[0 + j] ^ tmp[8 + j]
|
|
}
|
|
}
|
|
|
|
return [...Array(16).keys()].map(i => s[i])
|
|
}
|