~zooko/cryptopp/trunk

« back to all changes in this revision

Viewing changes to salsa.cpp

  • Committer: weidai
  • Date: 2003-07-29 01:18:33 UTC
  • Revision ID: svn-v4:57ff6487-cd31-0410-9ec3-f628ee90f5f0:trunk/c5:118
fix potential threading problem with initialization of static objects

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// salsa.cpp - written and placed in the public domain by Wei Dai
2
 
 
3
 
#include "pch.h"
4
 
#include "salsa.h"
5
 
#include "misc.h"
6
 
#include "argnames.h"
7
 
 
8
 
NAMESPACE_BEGIN(CryptoPP)
9
 
 
10
 
void Salsa20_TestInstantiations()
11
 
{
12
 
        Salsa20::Encryption x;
13
 
}
14
 
 
15
 
void Salsa20_Policy::GetNextIV(byte *IV) const
16
 
{
17
 
        word32 j6 = m_state[6] + 1;
18
 
        word32 j7 = m_state[7] + (j6 == 0);
19
 
 
20
 
        UnalignedPutWord(LITTLE_ENDIAN_ORDER, IV, j6);
21
 
        UnalignedPutWord(LITTLE_ENDIAN_ORDER, IV+4, j7);
22
 
}
23
 
 
24
 
void Salsa20_Policy::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
25
 
{
26
 
        m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20);
27
 
 
28
 
        if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20))
29
 
                throw InvalidRounds(StaticAlgorithmName(), m_rounds);
30
 
 
31
 
        GetUserKey(LITTLE_ENDIAN_ORDER, m_state+1, 4, key, 16);
32
 
        GetUserKey(LITTLE_ENDIAN_ORDER, m_state+11, 4, key + length - 16, 16);
33
 
 
34
 
        // m_state[0,5,10,15] forms "expand 16-byte k" or "expand 32-byte k"
35
 
        m_state[0] = 0x61707865;
36
 
        m_state[5] = (length == 16) ? 0x3120646e : 0x3320646e;
37
 
        m_state[10] = (length == 16) ? 0x79622d36 : 0x79622d32;
38
 
        m_state[15] = 0x6b206574;
39
 
}
40
 
 
41
 
void Salsa20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV)
42
 
{
43
 
        GetUserKey(LITTLE_ENDIAN_ORDER, m_state+6, 4, IV, 8);
44
 
}
45
 
 
46
 
void Salsa20_Policy::SeekToIteration(lword iterationCount)
47
 
{
48
 
        m_state[8] = (word32)iterationCount;
49
 
        m_state[9] = (word32)SafeRightShift<32>(iterationCount);
50
 
}
51
 
 
52
 
void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
53
 
{
54
 
        KeystreamOutput<LittleEndian> keystreamOutput(operation, output, input);
55
 
 
56
 
        word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
57
 
        word32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
58
 
 
59
 
        j0 = m_state[0];
60
 
        j1 = m_state[1];
61
 
        j2 = m_state[2];
62
 
        j3 = m_state[3];
63
 
        j4 = m_state[4];
64
 
        j5 = m_state[5];
65
 
        j6 = m_state[6];
66
 
        j7 = m_state[7];
67
 
        j8 = m_state[8];
68
 
        j9 = m_state[9];
69
 
        j10 = m_state[10];
70
 
        j11 = m_state[11];
71
 
        j12 = m_state[12];
72
 
        j13 = m_state[13];
73
 
        j14 = m_state[14];
74
 
        j15 = m_state[15];
75
 
 
76
 
        for (size_t iteration = 0; iteration < iterationCount; ++iteration)
77
 
        {
78
 
                x0 = j0;
79
 
                x1 = j1;
80
 
                x2 = j2;
81
 
                x3 = j3;
82
 
                x4 = j4;
83
 
                x5 = j5;
84
 
                x6 = j6;
85
 
                x7 = j7;
86
 
                x8 = j8;
87
 
                x9 = j9;
88
 
                x10 = j10;
89
 
                x11 = j11;
90
 
                x12 = j12;
91
 
                x13 = j13;
92
 
                x14 = j14;
93
 
                x15 = j15;
94
 
 
95
 
                for (int i=m_rounds; i>0; i-=2)
96
 
                {
97
 
#define QUARTER_ROUND(a, b, c, d)       \
98
 
        b = b ^ rotlFixed(a + d, 7);    \
99
 
        c = c ^ rotlFixed(b + a, 9);    \
100
 
        d = d ^ rotlFixed(c + b, 13);   \
101
 
        a = a ^ rotlFixed(d + c, 18);
102
 
 
103
 
                        QUARTER_ROUND(x0, x4, x8, x12)
104
 
                        QUARTER_ROUND(x5, x9, x13, x1)
105
 
                        QUARTER_ROUND(x10, x14, x2, x6)
106
 
                        QUARTER_ROUND(x15, x3, x7, x11)
107
 
 
108
 
                        QUARTER_ROUND(x0, x1, x2, x3)
109
 
                        QUARTER_ROUND(x5, x6, x7, x4)
110
 
                        QUARTER_ROUND(x10, x11, x8, x9)
111
 
                        QUARTER_ROUND(x15, x12, x13, x14)
112
 
                }
113
 
 
114
 
                keystreamOutput (x0 + j0)
115
 
                                                (x1 + j1)
116
 
                                                (x2 + j2)
117
 
                                                (x3 + j3)
118
 
                                                (x4 + j4)
119
 
                                                (x5 + j5)
120
 
                                                (x6 + j6)
121
 
                                                (x7 + j7)
122
 
                                                (x8 + j8)
123
 
                                                (x9 + j9)
124
 
                                                (x10 + j10)
125
 
                                                (x11 + j11)
126
 
                                                (x12 + j12)
127
 
                                                (x13 + j13)
128
 
                                                (x14 + j14)
129
 
                                                (x15 + j15);
130
 
 
131
 
                if (++j8 == 0)
132
 
                        ++j9;
133
 
        }
134
 
 
135
 
        m_state[8] = j8;
136
 
        m_state[9] = j9;
137
 
}
138
 
 
139
 
NAMESPACE_END