]>
iEval git - authen-passphrase-scrypt.git/blob - scrypt-1.2.1/lib/crypto/crypto_scrypt_smix.c
2 * Copyright 2009 Colin Percival
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * This file was originally written by Colin Percival as part of the Tarsnap
27 * online backup system.
31 #include "sysendian.h"
33 #include "crypto_scrypt_smix.h"
35 static void blkcpy(void *, const void *, size_t);
36 static void blkxor(void *, const void *, size_t);
37 static void salsa20_8(uint32_t[16]);
38 static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t);
39 static uint64_t integerify(const void *, size_t);
42 blkcpy(void * dest
, const void * src
, size_t len
)
45 const size_t * S
= src
;
46 size_t L
= len
/ sizeof(size_t);
49 for (i
= 0; i
< L
; i
++)
54 blkxor(void * dest
, const void * src
, size_t len
)
57 const size_t * S
= src
;
58 size_t L
= len
/ sizeof(size_t);
61 for (i
= 0; i
< L
; i
++)
67 * Apply the salsa20/8 core to the provided block.
70 salsa20_8(uint32_t B
[16])
76 for (i
= 0; i
< 8; i
+= 2) {
77 #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
78 /* Operate on columns. */
79 x
[ 4] ^= R(x
[ 0]+x
[12], 7); x
[ 8] ^= R(x
[ 4]+x
[ 0], 9);
80 x
[12] ^= R(x
[ 8]+x
[ 4],13); x
[ 0] ^= R(x
[12]+x
[ 8],18);
82 x
[ 9] ^= R(x
[ 5]+x
[ 1], 7); x
[13] ^= R(x
[ 9]+x
[ 5], 9);
83 x
[ 1] ^= R(x
[13]+x
[ 9],13); x
[ 5] ^= R(x
[ 1]+x
[13],18);
85 x
[14] ^= R(x
[10]+x
[ 6], 7); x
[ 2] ^= R(x
[14]+x
[10], 9);
86 x
[ 6] ^= R(x
[ 2]+x
[14],13); x
[10] ^= R(x
[ 6]+x
[ 2],18);
88 x
[ 3] ^= R(x
[15]+x
[11], 7); x
[ 7] ^= R(x
[ 3]+x
[15], 9);
89 x
[11] ^= R(x
[ 7]+x
[ 3],13); x
[15] ^= R(x
[11]+x
[ 7],18);
91 /* Operate on rows. */
92 x
[ 1] ^= R(x
[ 0]+x
[ 3], 7); x
[ 2] ^= R(x
[ 1]+x
[ 0], 9);
93 x
[ 3] ^= R(x
[ 2]+x
[ 1],13); x
[ 0] ^= R(x
[ 3]+x
[ 2],18);
95 x
[ 6] ^= R(x
[ 5]+x
[ 4], 7); x
[ 7] ^= R(x
[ 6]+x
[ 5], 9);
96 x
[ 4] ^= R(x
[ 7]+x
[ 6],13); x
[ 5] ^= R(x
[ 4]+x
[ 7],18);
98 x
[11] ^= R(x
[10]+x
[ 9], 7); x
[ 8] ^= R(x
[11]+x
[10], 9);
99 x
[ 9] ^= R(x
[ 8]+x
[11],13); x
[10] ^= R(x
[ 9]+x
[ 8],18);
101 x
[12] ^= R(x
[15]+x
[14], 7); x
[13] ^= R(x
[12]+x
[15], 9);
102 x
[14] ^= R(x
[13]+x
[12],13); x
[15] ^= R(x
[14]+x
[13],18);
105 for (i
= 0; i
< 16; i
++)
110 * blockmix_salsa8(Bin, Bout, X, r):
111 * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r
112 * bytes in length; the output Bout must also be the same size. The
113 * temporary space X must be 64 bytes.
116 blockmix_salsa8(const uint32_t * Bin
, uint32_t * Bout
, uint32_t * X
, size_t r
)
120 /* 1: X <-- B_{2r - 1} */
121 blkcpy(X
, &Bin
[(2 * r
- 1) * 16], 64);
123 /* 2: for i = 0 to 2r - 1 do */
124 for (i
= 0; i
< 2 * r
; i
+= 2) {
125 /* 3: X <-- H(X \xor B_i) */
126 blkxor(X
, &Bin
[i
* 16], 64);
130 /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
131 blkcpy(&Bout
[i
* 8], X
, 64);
133 /* 3: X <-- H(X \xor B_i) */
134 blkxor(X
, &Bin
[i
* 16 + 16], 64);
138 /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
139 blkcpy(&Bout
[i
* 8 + r
* 16], X
, 64);
145 * Return the result of parsing B_{2r-1} as a little-endian integer.
148 integerify(const void * B
, size_t r
)
150 const uint32_t * X
= (const void *)((uintptr_t)(B
) + (2 * r
- 1) * 64);
152 return (((uint64_t)(X
[1]) << 32) + X
[0]);
156 * crypto_scrypt_smix(B, r, N, V, XY):
157 * Compute B = SMix_r(B, N). The input B must be 128r bytes in length;
158 * the temporary storage V must be 128rN bytes in length; the temporary
159 * storage XY must be 256r + 64 bytes in length. The value N must be a
160 * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a
161 * multiple of 64 bytes.
164 crypto_scrypt_smix(uint8_t * B
, size_t r
, uint64_t N
, void * _V
, void * XY
)
167 uint32_t * Y
= (void *)((uint8_t *)(XY
) + 128 * r
);
168 uint32_t * Z
= (void *)((uint8_t *)(XY
) + 256 * r
);
175 for (k
= 0; k
< 32 * r
; k
++)
176 X
[k
] = le32dec(&B
[4 * k
]);
178 /* 2: for i = 0 to N - 1 do */
179 for (i
= 0; i
< N
; i
+= 2) {
181 blkcpy(&V
[i
* (32 * r
)], X
, 128 * r
);
184 blockmix_salsa8(X
, Y
, Z
, r
);
187 blkcpy(&V
[(i
+ 1) * (32 * r
)], Y
, 128 * r
);
190 blockmix_salsa8(Y
, X
, Z
, r
);
193 /* 6: for i = 0 to N - 1 do */
194 for (i
= 0; i
< N
; i
+= 2) {
195 /* 7: j <-- Integerify(X) mod N */
196 j
= integerify(X
, r
) & (N
- 1);
198 /* 8: X <-- H(X \xor V_j) */
199 blkxor(X
, &V
[j
* (32 * r
)], 128 * r
);
200 blockmix_salsa8(X
, Y
, Z
, r
);
202 /* 7: j <-- Integerify(X) mod N */
203 j
= integerify(Y
, r
) & (N
- 1);
205 /* 8: X <-- H(X \xor V_j) */
206 blkxor(Y
, &V
[j
* (32 * r
)], 128 * r
);
207 blockmix_salsa8(Y
, X
, Z
, r
);
211 for (k
= 0; k
< 32 * r
; k
++)
212 le32enc(&B
[4 * k
], X
[k
]);
This page took 0.049076 seconds and 4 git commands to generate.