mirrored from https://www.bouncycastle.org/repositories/bc-csharp
-
Notifications
You must be signed in to change notification settings - Fork 549
/
XSalsa20Engine.cs
64 lines (53 loc) · 2.06 KB
/
XSalsa20Engine.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using System;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines
{
/// <summary>
/// Implementation of Daniel J. Bernstein's XSalsa20 stream cipher - Salsa20 with an extended nonce.
/// </summary>
/// <remarks>
/// XSalsa20 requires a 256 bit key, and a 192 bit nonce.
/// </remarks>
public class XSalsa20Engine
: Salsa20Engine
{
public override string AlgorithmName
{
get { return "XSalsa20"; }
}
protected override int NonceSize
{
get { return 24; }
}
/// <summary>
/// XSalsa20 key generation: process 256 bit input key and 128 bits of the input nonce
/// using a core Salsa20 function without input addition to produce 256 bit working key
/// and use that with the remaining 64 bits of nonce to initialize a standard Salsa20 engine state.
/// </summary>
protected override void SetKey(byte[] keyBytes, byte[] ivBytes)
{
if (keyBytes == null)
throw new ArgumentException(AlgorithmName + " doesn't support re-init with null key");
if (keyBytes.Length != 32)
throw new ArgumentException(AlgorithmName + " requires a 256 bit key");
// Set key for HSalsa20
base.SetKey(keyBytes, ivBytes);
// Pack next 64 bits of IV into engine state instead of counter
Pack.LE_To_UInt32(ivBytes, 8, engineState, 8, 2);
// Process engine state to generate Salsa20 key
uint[] hsalsa20Out = new uint[engineState.Length];
SalsaCore(20, engineState, hsalsa20Out);
// Set new key, removing addition in last round of salsaCore
engineState[1] = hsalsa20Out[0] - engineState[0];
engineState[2] = hsalsa20Out[5] - engineState[5];
engineState[3] = hsalsa20Out[10] - engineState[10];
engineState[4] = hsalsa20Out[15] - engineState[15];
engineState[11] = hsalsa20Out[6] - engineState[6];
engineState[12] = hsalsa20Out[7] - engineState[7];
engineState[13] = hsalsa20Out[8] - engineState[8];
engineState[14] = hsalsa20Out[9] - engineState[9];
// Last 64 bits of input IV
Pack.LE_To_UInt32(ivBytes, 16, engineState, 6, 2);
}
}
}