Skip to content

Commit

Permalink
feat: v0.2.5 | Helper for encrytion process, improved docs
Browse files Browse the repository at this point in the history
  • Loading branch information
li0ard committed Feb 14, 2025
1 parent e836997 commit ab074f0
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 21 deletions.
2 changes: 1 addition & 1 deletion jsr.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@li0ard/crapto1-ts",
"version": "0.2.4",
"version": "0.2.5",
"exports": "./src/index.ts",
"publish": {
"include": [
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@li0ard/crapto1_ts",
"version": "0.2.4",
"version": "0.2.5",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
Expand Down
12 changes: 6 additions & 6 deletions src/crapto1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { bebit, binsearch, bit, evenParity32, extend_table, extend_table_simple,
/**
* Rollback the shift register in order to get previous states (for bits)
* @param s State
* @param in_ Bits
* @param isEncrypted Encrypted?
* @param in_ Input bit
* @param isEncrypted Is input bit encrypted?
* @returns {number}
*/
export const lfsr_rollback_bit = (s: Crypto1State, in_: number, isEncrypted: boolean = false): number => {
Expand All @@ -29,8 +29,8 @@ export const lfsr_rollback_bit = (s: Crypto1State, in_: number, isEncrypted: boo
/**
* Rollback the shift register in order to get previous states (for bytes)
* @param s State
* @param in_ Word
* @param isEncrypted Encrypted?
* @param in_ Input byte
* @param isEncrypted Is input byte encrypted?
* @returns {number}
*/
export const lfsr_rollback_byte = (s: Crypto1State, in_: number, isEncrypted: boolean = false): number => {
Expand All @@ -44,8 +44,8 @@ export const lfsr_rollback_byte = (s: Crypto1State, in_: number, isEncrypted: bo
/**
* Rollback the shift register in order to get previous states (for words (uint32))
* @param s State
* @param in_ Word
* @param isEncrypted Encrypted?
* @param in_ Input word
* @param isEncrypted Is input word encrypted?
* @returns {number}
*/
export const lfsr_rollback_word = (s: Crypto1State, in_: number, isEncrypted: boolean = false): number => {
Expand Down
38 changes: 27 additions & 11 deletions src/crypto1.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Crypto1State } from "./state";
import { bebit, bit, filter, parity, swapendian } from "./utils";
import { Crypto1State } from "./state";
import { bebit, bit, filter, oddParity8, parity, swapendian } from "./utils";

export const LF_POLY_ODD: number = 0x29CE5C;
export const LF_POLY_EVEN: number = 0x870804;
Expand All @@ -19,10 +19,10 @@ export const prng_successor = (x: number, n: number): number => {
}

/**
* Proceed Crypto1 encryption/decryption process (for words (uint32))
* Generate keystream for words (uint32)
* @param s State
* @param in_ Word
* @param isEncrypted Encrypted?
* @param in_ Input word
* @param isEncrypted Is input word encrypted?
* @returns {number}
*/
export const crypto1_word = (s: Crypto1State, in_: number, isEncrypted: boolean = false): number => {
Expand All @@ -34,10 +34,10 @@ export const crypto1_word = (s: Crypto1State, in_: number, isEncrypted: boolean
}

/**
* Proceed Crypto1 encryption/decryption process (for bytes)
* Generate keystream for bytes
* @param s State
* @param in_ Word
* @param isEncrypted Encrypted?
* @param in_ Input byte
* @param isEncrypted Is input byte encrypted?
* @returns {number}
*/
export const crypto1_byte = (s: Crypto1State, in_: number, isEncrypted: boolean = false): number => {
Expand All @@ -49,10 +49,10 @@ export const crypto1_byte = (s: Crypto1State, in_: number, isEncrypted: boolean
}

/**
* Proceed Crypto1 encryption/decryption process (for bits)
* Generate keystream for bits
* @param s State
* @param in_ Bit
* @param isEncrypted Encrypted?
* @param in_ Input bit
* @param isEncrypted Is input bit encrypted?
* @returns {number}
*/
export const crypto1_bit = (s: Crypto1State, in_: number, isEncrypted: boolean = false): number => {
Expand All @@ -67,4 +67,20 @@ export const crypto1_bit = (s: Crypto1State, in_: number, isEncrypted: boolean =
s.even ^= s.odd;
s.odd ^= s.even;
return ret;
}

/**
* Proceed encryption/decryption process
* @param s State
* @param data Input data
* @param isIn Use input data as input word for keystream generation?
* @returns {number[]}
*/
export const encrypt = (s: Crypto1State, data: number[], isIn: boolean = false): number[] => {
let result: number[] = []
for (let i = 0; i < data.length; i++) {
result[i] = data[i] ^ crypto1_byte(s, isIn ? data[i] : 0);
}

return result
}
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export { recovery32, recovery64, lfsr_recovery32, lfsr_recovery64, lfsr_rollback_bit, lfsr_rollback_byte, lfsr_rollback_word } from "./crapto1"
export { Crypto1State } from "./state"
export { prng_successor, crypto1_bit, crypto1_byte, crypto1_word } from "./crypto1"
export { prng_successor, crypto1_bit, crypto1_byte, crypto1_word, encrypt } from "./crypto1"
12 changes: 12 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export const parity = (x: number): number => {
return bit(0x6996, x & 0xf);
}

/**
* Binary search for the first occurence of stop's MSB in sorted
*/
export const binsearch = (data: number[], start: number, stop: number): number => {
let mid: number, val: number = data[stop] & 0xff000000;
while (start !== stop) {
Expand Down Expand Up @@ -62,13 +65,19 @@ export const quicksort = (data: number[], start: number, stop: number): void =>
quicksort(data, rit + 1, stop);
}

/**
* Helper, calculates the partial linear feedback contributions and puts in MSB
*/
export const update_contribution = (data: number[], item: number, mask1: number, mask2: number): void => {
let p: number = data[item] >>> 25;
p = p << 1 | parity(data[item] & mask1);
p = p << 1 | parity(data[item] & mask2);
data[item] = p << 24 | (data[item] & 0xffffff);
}

/**
* Using a bit of the keystream extend the table of possible lfsr states
*/
export const extend_table = (data: number[], tbl: number, end: number, bit: number, m1: number, m2: number, in_: number): number => {
in_ <<= 24;
for (data[tbl] <<= 1; tbl <= end; data[++tbl] <<= 1) {
Expand All @@ -90,6 +99,9 @@ export const extend_table = (data: number[], tbl: number, end: number, bit: numb
return end;
}

/**
* Using a bit of the keystream extend the table of possible lfsr states
*/
export const extend_table_simple = (tbl: number[], end: number, bit: number): number => {
let i = 0;
for (tbl[i] <<= 1; i <= end; tbl[++i] <<= 1) {
Expand Down
15 changes: 14 additions & 1 deletion tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from "bun:test"
import { Crypto1State, recovery32, recovery64 } from "../src/"
import { Crypto1State, encrypt, lfsr_rollback_byte, recovery32, recovery64 } from "../src/"
import { filter } from "../src/utils"

test("Recovery by 2 auths", () => {
Expand Down Expand Up @@ -64,3 +64,16 @@ test("State", () => {
expect(s.peekCrypto1Bit).toBe(filter(s.odd))
}
})

test("Encryption", () => {
let s = Crypto1State.fromKey(0x708076d3560en)
// Encrypt
expect(encrypt(s, [112, 147, 223, 153])).toEqual([48, 20, 167, 254])

// Rollback state
for(let i = 0; i < 4; i++) lfsr_rollback_byte(s, 0);
expect(s.lfsr).toBe(0x708076d3560en)

// Decrypt
expect(encrypt(s, [48, 20, 167, 254])).toEqual([112, 147, 223, 153])
})

0 comments on commit ab074f0

Please sign in to comment.