FFXIVLauncher-Netmaui

Форк
0
93 строки · 3.1 Кб
1
// NOTE: This file is copy-pasted almost *as-is* from the previous work `Aither.Crypto`
2
//       hence currently it does not follow XL's naming convetions.
3
//       
4
//       It's totally okay to change this. But for now, this is what it is atm.
5
// ReSharper disable InconsistentNaming
6

7
using System;
8
using System.Buffers.Binary;
9

10
namespace XIVLauncher.Common.Encryption.BlockCipher
11
{
12
    public sealed class Blowfish : IBlockCipher
13
    {
14
        /// <inheritdoc />
15
        public int BlockSize => 8;
16

17
        // NOTE: this field should never be marked as readonly as it actually creates a defensive copy on every access. (it's a trap)
18
        // https://devblogs.microsoft.com/premier-developer/the-in-modifier-and-the-readonly-structs-in-c/
19

20
        private BlowfishState m_state;
21

22
        /// <summary>
23
        /// Initializes a new instance of the Blowfish class.
24
        /// </summary>
25
        /// <remarks>
26
        /// This function also calculates P-array and S-boxes from the given key. This is most expensive operation in blowfish algorithm.
27
        /// </remarks>
28
        /// <param name="key">A secret key used for blowfish. Key length must be between 32 and 448 bits.</param>
29
        /// <exception cref="ArgumentException">Length of the key is either too short or too long.</exception>
30
        public Blowfish(ReadOnlySpan<byte> key)
31
        {
32
            m_state = new BlowfishState(key);
33
        }
34

35
        public unsafe void EncryptBlockUnsafe(byte* input, byte* output)
36
        {
37
            var inputBlock = (uint*)input;
38
            var outputBlock = (uint*)output;
39

40
            var xl = inputBlock[0];
41
            var xr = inputBlock[1];
42

43
            // will be elided by JIT
44
            if (BitConverter.IsLittleEndian)
45
            {
46
                xl = BinaryPrimitives.ReverseEndianness(xl);
47
                xr = BinaryPrimitives.ReverseEndianness(xr);
48
            }
49

50
            (xl, xr) = m_state.EncryptBlock(xl, xr);
51

52
            // will be elided by JIT
53
            if (BitConverter.IsLittleEndian)
54
            {
55
                xl = BinaryPrimitives.ReverseEndianness(xl);
56
                xr = BinaryPrimitives.ReverseEndianness(xr);
57
            }
58

59
            outputBlock[0] = xl;
60
            outputBlock[1] = xr;
61
        }
62

63
        public unsafe void DecryptBlockUnsafe(byte* input, byte* output)
64
        {
65
            var inputBlock = (uint*)input;
66
            var outputBlock = (uint*)output;
67

68
            var xl = inputBlock[0];
69
            var xr = inputBlock[1];
70

71
            // will be elided by JIT
72
            if (BitConverter.IsLittleEndian)
73
            {
74
                xl = BinaryPrimitives.ReverseEndianness(xl);
75
                xr = BinaryPrimitives.ReverseEndianness(xr);
76
            }
77

78
            (xl, xr) = m_state.DecryptBlock(xl, xr);
79

80
            // will be elided by JIT
81
            if (BitConverter.IsLittleEndian)
82
            {
83
                xl = BinaryPrimitives.ReverseEndianness(xl);
84
                xr = BinaryPrimitives.ReverseEndianness(xr);
85
            }
86

87
            outputBlock[0] = xl;
88
            outputBlock[1] = xr;
89
        }
90
    }
91
}
92

93
// ReSharper restore InconsistentNaming
94

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.