| 1 | module blowfish |
| 2 | |
| 3 | pub struct Blowfish { |
| 4 | pub mut: |
| 5 | p [18]u32 |
| 6 | s [4][256]u32 |
| 7 | } |
| 8 | |
| 9 | // new_cipher creates and returns a new Blowfish cipher. |
| 10 | // The key argument should be the Blowfish key, from 1 to 56 bytes. |
| 11 | pub fn new_cipher(key []u8) !Blowfish { |
| 12 | mut bf := Blowfish{} |
| 13 | unsafe { vmemcpy(&bf.p[0], &p[0], int(sizeof(bf.p))) } |
| 14 | unsafe { vmemcpy(&bf.s[0], &s[0], int(sizeof(bf.s))) } |
| 15 | if key.len < 1 || key.len > 56 { |
| 16 | return error('invalid key') |
| 17 | } |
| 18 | expand_key(key, mut bf) |
| 19 | |
| 20 | return bf |
| 21 | } |
| 22 | |
| 23 | // new_salted_cipher returns a new Blowfish cipher that folds a salt into its key schedule. |
| 24 | pub fn new_salted_cipher(key []u8, salt []u8) !Blowfish { |
| 25 | if salt.len == 0 { |
| 26 | return new_cipher(key) |
| 27 | } |
| 28 | mut bf := Blowfish{} |
| 29 | unsafe { vmemcpy(&bf.p[0], &p[0], int(sizeof(bf.p))) } |
| 30 | unsafe { vmemcpy(&bf.s[0], &s[0], int(sizeof(bf.s))) } |
| 31 | if key.len < 1 { |
| 32 | return error('invalid key') |
| 33 | } |
| 34 | expand_key_with_salt(key, salt, mut bf) |
| 35 | return bf |
| 36 | } |
| 37 | |
| 38 | // encrypt encrypts the 8-byte buffer src using the key k and stores the result in dst. |
| 39 | pub fn (mut bf Blowfish) encrypt(mut dst []u8, src []u8) { |
| 40 | mut l := u32(src[0]) << 24 | u32(src[1]) << 16 | u32(src[2]) << 8 | u32(src[3]) |
| 41 | mut r := u32(src[4]) << 24 | u32(src[5]) << 16 | u32(src[6]) << 8 | u32(src[7]) |
| 42 | l, r = setup_tables(l, r, mut bf) |
| 43 | dst[0], dst[1], dst[2], dst[3] = u8(l >> 24), u8(l >> 16), u8(l >> 8), u8(l) |
| 44 | dst[4], dst[5], dst[6], dst[7] = u8(r >> 24), u8(r >> 16), u8(r >> 8), u8(r) |
| 45 | } |
| 46 | |