romulus-js/src/skinny-128-384-plus.ts
Jack Hadrill 1998293b65
All checks were successful
continuous-integration/drone/push Build is passing
Add encrypt method
2022-01-29 22:25:00 +00:00

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])
}