Compare commits

..

29 Commits

Author SHA1 Message Date
7290fa2366 trivial 2025-01-23 19:33:05 +09:00
12587a70ca Add desc 2025-01-23 15:16:02 +09:00
77c4e048ae Update README.md 2025-01-23 12:24:11 +09:00
f02b765b93 Update and migrate 2025-01-23 12:18:26 +09:00
Tino Breddin
b5f27a29ba
Merge pull request #2 from aeternity/tb-format-literal
Use fprintf with proper format template
2019-11-18 13:00:21 +01:00
Tino Breddin
c566c373e5 Use fprintf with proper format template
This fixes an issue where GCC will warn about `format-nonliteral`,
which can break compilation.
2019-11-18 12:49:19 +01:00
Tino Breddin
c818ddc200
Merge pull request #1 from tolbrino/tb-rebar3-win32
Update to rebar3 and add win32 support
2018-12-11 14:43:04 +01:00
Tino Breddin
9dd731eff0 Update to rebar3 and add win32 support 2018-12-10 17:02:18 +01:00
Paul Oliver
779828302e
Merge pull request #5 from puzza007/update-ci-otp-versions
Add OTP 19.1, 20.1 and 21.0 to Travis builds
2018-08-01 12:38:27 +12:00
Paul Oliver
e0c9f692e2
Bump vsn to 0.1.2 2018-08-01 11:47:57 +12:00
Paul Oliver
c4fe944262
Remove makefile 2018-08-01 11:47:28 +12:00
Paul Oliver
b4fc3fc5a6
Rely on builtin rebar3 2018-08-01 11:37:58 +12:00
Paul Oliver
c4fa6cd8a5
Add OTP 19.1, 20.1 and 21.0 to Travis builds 2018-08-01 11:32:13 +12:00
Paul Oliver
be3d418c5a Merge pull request #4 from puzza007/add-hexhash
Add hexhash/2
2016-08-06 19:54:47 +12:00
Paul Oliver
b10f9f7327
Ditch old OTP releases 2016-08-06 19:48:55 +12:00
Paul Oliver
b80fa2d97a
Cache $HOME/.cache/rebar3/ in Travis CI 2016-08-06 19:42:31 +12:00
Paul Oliver
b89e8e27c3
Fix Travis build 2016-08-06 19:38:10 +12:00
Paul Oliver
e963bef653
Add hexhash/2 2016-08-06 19:33:06 +12:00
Paul Oliver
c67eb9fae6 Merge pull request #3 from puzza007/fix-so-name
Fix so name
2016-08-06 18:34:06 +12:00
Paul Oliver
fcce31c89d Fix so name 2016-08-06 18:21:15 +12:00
Paul Oliver
8721fc5571 Merge pull request #2 from puzza007/ci-more-otp-versions
CI including OTP 18.x
2016-08-06 17:57:53 +12:00
Paul Oliver
b32d762586
CI including OTP 18.x 2016-08-06 17:54:24 +12:00
Paul Oliver
9be468d949 Merge pull request #1 from puzza007/rebar3
Move to rebar3
2016-08-06 17:45:31 +12:00
Paul Oliver
a151d3d2ed
Move to rebar3 2016-08-06 17:40:55 +12:00
SUZUKI Tetsuya
74575bcc72 change version 2012-10-07 16:55:46 +09:00
SUZUKI Tetsuya
8ab8cc4670 update 2012-10-07 16:55:36 +09:00
SUZUKI Tetsuya
6f28f39e3b changes functions to static 2012-10-07 16:52:36 +09:00
SUZUKI Tetsuya
9bd9083370 remove unused files 2012-10-07 16:45:43 +09:00
SUZUKI Tetsuya
e20d5d08c4 write edoc 2012-10-03 17:33:04 +09:00
43 changed files with 1080 additions and 9822 deletions

3
.gitignore vendored
View File

@ -12,3 +12,6 @@ priv
edoc-info
stylesheet.css
_build
/TEST-file_"sha3.app".xml
/TEST-file_sha3.app.xml

View File

@ -1,12 +1,17 @@
language: erlang
script: rebar3 update && rebar3 eunit && rebar3 dialyzer
notifications:
disabled: true
branches:
only:
- develop
- 0.1.0
otp_release:
- R15B02
- R15B01
- R15B
otp_release:
- 18.2
- 19.1
- 20.1
- 21.0
cache:
directories:
- $HOME/.cache/rebar3/

1
Emakefile Normal file
View File

@ -0,0 +1 @@
{"src/*", [debug_info, {i, "include/"}, {outdir, "ebin/"}]}.

203
LICENSE Normal file
View File

@ -0,0 +1,203 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2018 SUZUKI Tetsuya <tetsuya.suzuki@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,23 +0,0 @@
.PHONY: doc
all:
./rebar compile
./rebar doc
./rebar xref
./rebar eunit
compile:
./rebar compile
doc:
./rebar doc
xref: compile
./rebar xref
clean:
./rebar clean
test: xref
./rebar eunit

View File

@ -1,21 +1,30 @@
erlang-sha3
===========
[![Build Status](https://secure.travis-ci.org/szktty/erlang-sha3.png?branch=develop)](http://travis-ci.org/szktty/erlang-sha3)
This repository contains:
1. the original 64-bit SHA-3 NIF library (forked from https://github.com/szktty/erlang-sha3 )
2. Complete native Erlang fallback functions for both the Keccak and SHA-3 variants of the underlying algorithm
SHA3 for Erlang
The native Erlang version of the function not only provides a more complete cross-platform implementation than either
the original Keccak C library and the current SHA-3 implementation that ships with the Erlang stdlib.
This is also by far the most readable and understandable implementation in any language currently.
If you are a student of the Keccack hashing algorithm, the code in this repository is extremely useful.
Peter Harpending wrote the original implementation with readability in mind,
and Hans Svensson greatly improved the performance of the readable implementation.
Licenses
--------
This program is distributed under Apache License 2.0.
This program is distributed under the Apache License 2.0
Keccak source files are distributed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication license.
Author
Authors
------
SUZUKI Tetsuya <tetsuya.suzuki@gmail.com>
Orginal NIF wrapper: SUZUKI Tetsuya <tetsuya.suzuki@gmail.com>
Native Erlang functions: Peter Harpending, Hans Svensson, Craig Everett

View File

@ -1,27 +0,0 @@
/*
File: AVR8-rotate64.h
This code is originally by Daniel Otte (daniel.otte@rub.de) in 2006-2010 as part of the AVR-Crypto-Lib, and was then improved by Ronny Van Keer, STMicroelectronics, in 2010.
Implementation by Daniel Otte and Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef ROTATE64_H_
#define ROTATE64_H_
#include <stdint.h>
#define ROT_CODE(a) ((((a)/8+((((a)%8)>4)?1:0))<<4) | ((a) & 7))
uint64_t rotate64_1bit_left(uint64_t a);
uint64_t rotate64_1bit_right(uint64_t a);
uint64_t rotate64left_code(uint64_t a, int8_t code);
#endif /* ROTATE64_H_ */

View File

@ -1,285 +0,0 @@
/*
File: AVR8-rotate64.s
This code is originally by Daniel Otte (daniel.otte@rub.de) in 2006-2010 as part of the AVR-Crypto-Lib, and was then improved by Ronny Van Keer, STMicroelectronics, in 2010.
Implementation by Daniel Otte and Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
.global rotate64_1bit_left
rotate64_4bit_left:
lsl r18
rol r19
rol r20
rol r21
rol r22
rol r23
rol r24
rol r25
adc r18, r1
rotate64_3bit_left:
lsl r18
rol r19
rol r20
rol r21
rol r22
rol r23
rol r24
rol r25
adc r18, r1
rotate64_2bit_left:
lsl r18
rol r19
rol r20
rol r21
rol r22
rol r23
rol r24
rol r25
adc r18, r1
rotate64_1bit_left:
lsl r18
rol r19
rol r20
rol r21
rol r22
rol r23
rol r24
rol r25
adc r18, r1
ret
.global rotate64_1bit_right
rotate64_3bit_right:
bst r18, 0
ror r25
ror r24
ror r23
ror r22
ror r21
ror r20
ror r19
ror r18
bld r25, 7
rotate64_2bit_right:
bst r18, 0
ror r25
ror r24
ror r23
ror r22
ror r21
ror r20
ror r19
ror r18
bld r25, 7
rotate64_1bit_right:
bst r18, 0
ror r25
ror r24
ror r23
ror r22
ror r21
ror r20
ror r19
ror r18
bld r25, 7
ret
/*
** Each byte rotate routine must be 16 instructions long.
*/
rotate64_0byte_left:
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
rotate64_1byte_left:
mov r0, r25
mov r25, r24
mov r24, r23
mov r23, r22
mov r22, r21
mov r21, r20
mov r20, r19
mov r19, r18
mov r18, r0
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
rotate64_2byte_left:
movw r0, r24
movw r24, r22
movw r22, r20
movw r20, r18
movw r18, r0
clr r1
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
nop
nop
nop
rotate64_3byte_left:
mov r0, r25
mov r25, r22
mov r22, r19
mov r19, r24
mov r24, r21
mov r21, r18
mov r18, r23
mov r23, r20
mov r20, r0
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
rotate64_4byte_left:
movw r0, r24
movw r24, r20
movw r20, r0
movw r0, r22
movw r22, r18
movw r18, r0
clr r1
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
nop
nop
rotate64_5byte_left:
mov r0, r25
mov r25, r20
mov r20, r23
mov r23, r18
mov r18, r21
mov r21, r24
mov r24, r19
mov r19, r22
mov r22, r0
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
rotate64_6byte_left:
movw r0, r18
movw r18, r20
movw r20, r22
movw r22, r24
movw r24, r0
clr r1
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
nop
nop
nop
rotate64_7byte_left:
mov r0, r18
mov r18, r19
mov r19, r20
mov r20, r21
mov r21, r22
mov r22, r23
mov r23, r24
mov r24, r25
mov r25, r0
andi r16, 0x07
ldi r30, pm_lo8(bit_rot_jmp_table)
ldi r31, pm_hi8(bit_rot_jmp_table)
add r30, r16
adc r31, r1
ijmp
nop
bit_rot_jmp_table:
ret
rjmp rotate64_1bit_left
rjmp rotate64_2bit_left
rjmp rotate64_3bit_left
rjmp rotate64_4bit_left
rjmp rotate64_3bit_right
rjmp rotate64_2bit_right
rjmp rotate64_1bit_right
.global rotate64left_code
rotate64left_code:
ldi r30, pm_lo8(rotate64_0byte_left)
ldi r31, pm_hi8(rotate64_0byte_left)
mov r0, r16
andi r16, 0x70
add r30, r16
adc r31, r1
mov r16, r0
ijmp

View File

@ -1,2 +0,0 @@
#define cKeccakR 1088
#define cKeccakFixedOutputLengthInBytes 32

View File

@ -1,555 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
static const UINT32 KeccakF1600RoundConstants_int2[2*24] =
{
0x00000001UL, 0x00000000UL,
0x00000000UL, 0x00000089UL,
0x00000000UL, 0x8000008bUL,
0x00000000UL, 0x80008080UL,
0x00000001UL, 0x0000008bUL,
0x00000001UL, 0x00008000UL,
0x00000001UL, 0x80008088UL,
0x00000001UL, 0x80000082UL,
0x00000000UL, 0x0000000bUL,
0x00000000UL, 0x0000000aUL,
0x00000001UL, 0x00008082UL,
0x00000000UL, 0x00008003UL,
0x00000001UL, 0x0000808bUL,
0x00000001UL, 0x8000000bUL,
0x00000001UL, 0x8000008aUL,
0x00000001UL, 0x80000081UL,
0x00000000UL, 0x80000081UL,
0x00000000UL, 0x80000008UL,
0x00000000UL, 0x00000083UL,
0x00000000UL, 0x80008003UL,
0x00000001UL, 0x80008088UL,
0x00000000UL, 0x80000088UL,
0x00000001UL, 0x00008000UL,
0x00000000UL, 0x80008082UL
};
#undef rounds
#define rounds \
{ \
UINT32 Da0, De0, Di0, Do0, Du0; \
UINT32 Da1, De1, Di1, Do1, Du1; \
UINT32 Ba, Be, Bi, Bo, Bu; \
UINT32 Aba0, Abe0, Abi0, Abo0, Abu0; \
UINT32 Aba1, Abe1, Abi1, Abo1, Abu1; \
UINT32 Aga0, Age0, Agi0, Ago0, Agu0; \
UINT32 Aga1, Age1, Agi1, Ago1, Agu1; \
UINT32 Aka0, Ake0, Aki0, Ako0, Aku0; \
UINT32 Aka1, Ake1, Aki1, Ako1, Aku1; \
UINT32 Ama0, Ame0, Ami0, Amo0, Amu0; \
UINT32 Ama1, Ame1, Ami1, Amo1, Amu1; \
UINT32 Asa0, Ase0, Asi0, Aso0, Asu0; \
UINT32 Asa1, Ase1, Asi1, Aso1, Asu1; \
UINT32 Cw, Cx, Cy, Cz; \
UINT32 Eba0, Ebe0, Ebi0, Ebo0, Ebu0; \
UINT32 Eba1, Ebe1, Ebi1, Ebo1, Ebu1; \
UINT32 Ega0, Ege0, Egi0, Ego0, Egu0; \
UINT32 Ega1, Ege1, Egi1, Ego1, Egu1; \
UINT32 Eka0, Eke0, Eki0, Eko0, Eku0; \
UINT32 Eka1, Eke1, Eki1, Eko1, Eku1; \
UINT32 Ema0, Eme0, Emi0, Emo0, Emu0; \
UINT32 Ema1, Eme1, Emi1, Emo1, Emu1; \
UINT32 Esa0, Ese0, Esi0, Eso0, Esu0; \
UINT32 Esa1, Ese1, Esi1, Eso1, Esu1; \
const UINT32 * pRoundConstants = KeccakF1600RoundConstants_int2; \
UINT32 i; \
\
copyFromState(A, state) \
\
for( i = 12; i != 0; --i ) { \
Cx = Abu0^Agu0^Aku0^Amu0^Asu0; \
Du1 = Abe1^Age1^Ake1^Ame1^Ase1; \
Da0 = Cx^ROL32(Du1, 1); \
Cz = Abu1^Agu1^Aku1^Amu1^Asu1; \
Du0 = Abe0^Age0^Ake0^Ame0^Ase0; \
Da1 = Cz^Du0; \
\
Cw = Abi0^Agi0^Aki0^Ami0^Asi0; \
Do0 = Cw^ROL32(Cz, 1); \
Cy = Abi1^Agi1^Aki1^Ami1^Asi1; \
Do1 = Cy^Cx; \
\
Cx = Aba0^Aga0^Aka0^Ama0^Asa0; \
De0 = Cx^ROL32(Cy, 1); \
Cz = Aba1^Aga1^Aka1^Ama1^Asa1; \
De1 = Cz^Cw; \
\
Cy = Abo1^Ago1^Ako1^Amo1^Aso1; \
Di0 = Du0^ROL32(Cy, 1); \
Cw = Abo0^Ago0^Ako0^Amo0^Aso0; \
Di1 = Du1^Cw; \
\
Du0 = Cw^ROL32(Cz, 1); \
Du1 = Cy^Cx; \
\
Aba0 ^= Da0; \
Ba = Aba0; \
Age0 ^= De0; \
Be = ROL32(Age0, 22); \
Aki1 ^= Di1; \
Bi = ROL32(Aki1, 22); \
Amo1 ^= Do1; \
Bo = ROL32(Amo1, 11); \
Asu0 ^= Du0; \
Bu = ROL32(Asu0, 7); \
Eba0 = Ba ^((~Be)& Bi ) ^ *(pRoundConstants++); \
Ebe0 = Be ^((~Bi)& Bo ); \
Ebi0 = Bi ^((~Bo)& Bu ); \
Ebo0 = Bo ^((~Bu)& Ba ); \
Ebu0 = Bu ^((~Ba)& Be ); \
\
Abo0 ^= Do0; \
Ba = ROL32(Abo0, 14); \
Agu0 ^= Du0; \
Be = ROL32(Agu0, 10); \
Aka1 ^= Da1; \
Bi = ROL32(Aka1, 2); \
Ame1 ^= De1; \
Bo = ROL32(Ame1, 23); \
Asi1 ^= Di1; \
Bu = ROL32(Asi1, 31); \
Ega0 = Ba ^((~Be)& Bi ); \
Ege0 = Be ^((~Bi)& Bo ); \
Egi0 = Bi ^((~Bo)& Bu ); \
Ego0 = Bo ^((~Bu)& Ba ); \
Egu0 = Bu ^((~Ba)& Be ); \
\
Abe1 ^= De1; \
Ba = ROL32(Abe1, 1); \
Agi0 ^= Di0; \
Be = ROL32(Agi0, 3); \
Ako1 ^= Do1; \
Bi = ROL32(Ako1, 13); \
Amu0 ^= Du0; \
Bo = ROL32(Amu0, 4); \
Asa0 ^= Da0; \
Bu = ROL32(Asa0, 9); \
Eka0 = Ba ^((~Be)& Bi ); \
Eke0 = Be ^((~Bi)& Bo ); \
Eki0 = Bi ^((~Bo)& Bu ); \
Eko0 = Bo ^((~Bu)& Ba ); \
Eku0 = Bu ^((~Ba)& Be ); \
\
Abu1 ^= Du1; \
Ba = ROL32(Abu1, 14); \
Aga0 ^= Da0; \
Be = ROL32(Aga0, 18); \
Ake0 ^= De0; \
Bi = ROL32(Ake0, 5); \
Ami1 ^= Di1; \
Bo = ROL32(Ami1, 8); \
Aso0 ^= Do0; \
Bu = ROL32(Aso0, 28); \
Ema0 = Ba ^((~Be)& Bi ); \
Eme0 = Be ^((~Bi)& Bo ); \
Emi0 = Bi ^((~Bo)& Bu ); \
Emo0 = Bo ^((~Bu)& Ba ); \
Emu0 = Bu ^((~Ba)& Be ); \
\
Abi0 ^= Di0; \
Ba = ROL32(Abi0, 31); \
Ago1 ^= Do1; \
Be = ROL32(Ago1, 28); \
Aku1 ^= Du1; \
Bi = ROL32(Aku1, 20); \
Ama1 ^= Da1; \
Bo = ROL32(Ama1, 21); \
Ase0 ^= De0; \
Bu = ROL32(Ase0, 1); \
Esa0 = Ba ^((~Be)& Bi ); \
Ese0 = Be ^((~Bi)& Bo ); \
Esi0 = Bi ^((~Bo)& Bu ); \
Eso0 = Bo ^((~Bu)& Ba ); \
Esu0 = Bu ^((~Ba)& Be ); \
\
Aba1 ^= Da1; \
Ba = Aba1; \
Age1 ^= De1; \
Be = ROL32(Age1, 22); \
Aki0 ^= Di0; \
Bi = ROL32(Aki0, 21); \
Amo0 ^= Do0; \
Bo = ROL32(Amo0, 10); \
Asu1 ^= Du1; \
Bu = ROL32(Asu1, 7); \
Eba1 = Ba ^((~Be)& Bi ); \
Eba1 ^= *(pRoundConstants++); \
Ebe1 = Be ^((~Bi)& Bo ); \
Ebi1 = Bi ^((~Bo)& Bu ); \
Ebo1 = Bo ^((~Bu)& Ba ); \
Ebu1 = Bu ^((~Ba)& Be ); \
\
Abo1 ^= Do1; \
Ba = ROL32(Abo1, 14); \
Agu1 ^= Du1; \
Be = ROL32(Agu1, 10); \
Aka0 ^= Da0; \
Bi = ROL32(Aka0, 1); \
Ame0 ^= De0; \
Bo = ROL32(Ame0, 22); \
Asi0 ^= Di0; \
Bu = ROL32(Asi0, 30); \
Ega1 = Ba ^((~Be)& Bi ); \
Ege1 = Be ^((~Bi)& Bo ); \
Egi1 = Bi ^((~Bo)& Bu ); \
Ego1 = Bo ^((~Bu)& Ba ); \
Egu1 = Bu ^((~Ba)& Be ); \
\
Abe0 ^= De0; \
Ba = Abe0; \
Agi1 ^= Di1; \
Be = ROL32(Agi1, 3); \
Ako0 ^= Do0; \
Bi = ROL32(Ako0, 12); \
Amu1 ^= Du1; \
Bo = ROL32(Amu1, 4); \
Asa1 ^= Da1; \
Bu = ROL32(Asa1, 9); \
Eka1 = Ba ^((~Be)& Bi ); \
Eke1 = Be ^((~Bi)& Bo ); \
Eki1 = Bi ^((~Bo)& Bu ); \
Eko1 = Bo ^((~Bu)& Ba ); \
Eku1 = Bu ^((~Ba)& Be ); \
\
Abu0 ^= Du0; \
Ba = ROL32(Abu0, 13); \
Aga1 ^= Da1; \
Be = ROL32(Aga1, 18); \
Ake1 ^= De1; \
Bi = ROL32(Ake1, 5); \
Ami0 ^= Di0; \
Bo = ROL32(Ami0, 7); \
Aso1 ^= Do1; \
Bu = ROL32(Aso1, 28); \
Ema1 = Ba ^((~Be)& Bi ); \
Eme1 = Be ^((~Bi)& Bo ); \
Emi1 = Bi ^((~Bo)& Bu ); \
Emo1 = Bo ^((~Bu)& Ba ); \
Emu1 = Bu ^((~Ba)& Be ); \
\
Abi1 ^= Di1; \
Ba = ROL32(Abi1, 31); \
Ago0 ^= Do0; \
Be = ROL32(Ago0, 27); \
Aku0 ^= Du0; \
Bi = ROL32(Aku0, 19); \
Ama0 ^= Da0; \
Bo = ROL32(Ama0, 20); \
Ase1 ^= De1; \
Bu = ROL32(Ase1, 1); \
Esa1 = Ba ^((~Be)& Bi ); \
Ese1 = Be ^((~Bi)& Bo ); \
Esi1 = Bi ^((~Bo)& Bu ); \
Eso1 = Bo ^((~Bu)& Ba ); \
Esu1 = Bu ^((~Ba)& Be ); \
\
Cx = Ebu0^Egu0^Eku0^Emu0^Esu0; \
Du1 = Ebe1^Ege1^Eke1^Eme1^Ese1; \
Da0 = Cx^ROL32(Du1, 1); \
Cz = Ebu1^Egu1^Eku1^Emu1^Esu1; \
Du0 = Ebe0^Ege0^Eke0^Eme0^Ese0; \
Da1 = Cz^Du0; \
\
Cw = Ebi0^Egi0^Eki0^Emi0^Esi0; \
Do0 = Cw^ROL32(Cz, 1); \
Cy = Ebi1^Egi1^Eki1^Emi1^Esi1; \
Do1 = Cy^Cx; \
\
Cx = Eba0^Ega0^Eka0^Ema0^Esa0; \
De0 = Cx^ROL32(Cy, 1); \
Cz = Eba1^Ega1^Eka1^Ema1^Esa1; \
De1 = Cz^Cw; \
\
Cy = Ebo1^Ego1^Eko1^Emo1^Eso1; \
Di0 = Du0^ROL32(Cy, 1); \
Cw = Ebo0^Ego0^Eko0^Emo0^Eso0; \
Di1 = Du1^Cw; \
\
Du0 = Cw^ROL32(Cz, 1); \
Du1 = Cy^Cx; \
\
Eba0 ^= Da0; \
Ba = Eba0; \
Ege0 ^= De0; \
Be = ROL32(Ege0, 22); \
Eki1 ^= Di1; \
Bi = ROL32(Eki1, 22); \
Emo1 ^= Do1; \
Bo = ROL32(Emo1, 11); \
Esu0 ^= Du0; \
Bu = ROL32(Esu0, 7); \
Aba0 = Ba ^((~Be)& Bi ); \
Aba0 ^= *(pRoundConstants++); \
Abe0 = Be ^((~Bi)& Bo ); \
Abi0 = Bi ^((~Bo)& Bu ); \
Abo0 = Bo ^((~Bu)& Ba ); \
Abu0 = Bu ^((~Ba)& Be ); \
\
Ebo0 ^= Do0; \
Ba = ROL32(Ebo0, 14); \
Egu0 ^= Du0; \
Be = ROL32(Egu0, 10); \
Eka1 ^= Da1; \
Bi = ROL32(Eka1, 2); \
Eme1 ^= De1; \
Bo = ROL32(Eme1, 23); \
Esi1 ^= Di1; \
Bu = ROL32(Esi1, 31); \
Aga0 = Ba ^((~Be)& Bi ); \
Age0 = Be ^((~Bi)& Bo ); \
Agi0 = Bi ^((~Bo)& Bu ); \
Ago0 = Bo ^((~Bu)& Ba ); \
Agu0 = Bu ^((~Ba)& Be ); \
\
Ebe1 ^= De1; \
Ba = ROL32(Ebe1, 1); \
Egi0 ^= Di0; \
Be = ROL32(Egi0, 3); \
Eko1 ^= Do1; \
Bi = ROL32(Eko1, 13); \
Emu0 ^= Du0; \
Bo = ROL32(Emu0, 4); \
Esa0 ^= Da0; \
Bu = ROL32(Esa0, 9); \
Aka0 = Ba ^((~Be)& Bi ); \
Ake0 = Be ^((~Bi)& Bo ); \
Aki0 = Bi ^((~Bo)& Bu ); \
Ako0 = Bo ^((~Bu)& Ba ); \
Aku0 = Bu ^((~Ba)& Be ); \
\
Ebu1 ^= Du1; \
Ba = ROL32(Ebu1, 14); \
Ega0 ^= Da0; \
Be = ROL32(Ega0, 18); \
Eke0 ^= De0; \
Bi = ROL32(Eke0, 5); \
Emi1 ^= Di1; \
Bo = ROL32(Emi1, 8); \
Eso0 ^= Do0; \
Bu = ROL32(Eso0, 28); \
Ama0 = Ba ^((~Be)& Bi ); \
Ame0 = Be ^((~Bi)& Bo ); \
Ami0 = Bi ^((~Bo)& Bu ); \
Amo0 = Bo ^((~Bu)& Ba ); \
Amu0 = Bu ^((~Ba)& Be ); \
\
Ebi0 ^= Di0; \
Ba = ROL32(Ebi0, 31); \
Ego1 ^= Do1; \
Be = ROL32(Ego1, 28); \
Eku1 ^= Du1; \
Bi = ROL32(Eku1, 20); \
Ema1 ^= Da1; \
Bo = ROL32(Ema1, 21); \
Ese0 ^= De0; \
Bu = ROL32(Ese0, 1); \
Asa0 = Ba ^((~Be)& Bi ); \
Ase0 = Be ^((~Bi)& Bo ); \
Asi0 = Bi ^((~Bo)& Bu ); \
Aso0 = Bo ^((~Bu)& Ba ); \
Asu0 = Bu ^((~Ba)& Be ); \
\
Eba1 ^= Da1; \
Ba = Eba1; \
Ege1 ^= De1; \
Be = ROL32(Ege1, 22); \
Eki0 ^= Di0; \
Bi = ROL32(Eki0, 21); \
Emo0 ^= Do0; \
Bo = ROL32(Emo0, 10); \
Esu1 ^= Du1; \
Bu = ROL32(Esu1, 7); \
Aba1 = Ba ^((~Be)& Bi ); \
Aba1 ^= *(pRoundConstants++); \
Abe1 = Be ^((~Bi)& Bo ); \
Abi1 = Bi ^((~Bo)& Bu ); \
Abo1 = Bo ^((~Bu)& Ba ); \
Abu1 = Bu ^((~Ba)& Be ); \
\
Ebo1 ^= Do1; \
Ba = ROL32(Ebo1, 14); \
Egu1 ^= Du1; \
Be = ROL32(Egu1, 10); \
Eka0 ^= Da0; \
Bi = ROL32(Eka0, 1); \
Eme0 ^= De0; \
Bo = ROL32(Eme0, 22); \
Esi0 ^= Di0; \
Bu = ROL32(Esi0, 30); \
Aga1 = Ba ^((~Be)& Bi ); \
Age1 = Be ^((~Bi)& Bo ); \
Agi1 = Bi ^((~Bo)& Bu ); \
Ago1 = Bo ^((~Bu)& Ba ); \
Agu1 = Bu ^((~Ba)& Be ); \
\
Ebe0 ^= De0; \
Ba = Ebe0; \
Egi1 ^= Di1; \
Be = ROL32(Egi1, 3); \
Eko0 ^= Do0; \
Bi = ROL32(Eko0, 12); \
Emu1 ^= Du1; \
Bo = ROL32(Emu1, 4); \
Esa1 ^= Da1; \
Bu = ROL32(Esa1, 9); \
Aka1 = Ba ^((~Be)& Bi ); \
Ake1 = Be ^((~Bi)& Bo ); \
Aki1 = Bi ^((~Bo)& Bu ); \
Ako1 = Bo ^((~Bu)& Ba ); \
Aku1 = Bu ^((~Ba)& Be ); \
\
Ebu0 ^= Du0; \
Ba = ROL32(Ebu0, 13); \
Ega1 ^= Da1; \
Be = ROL32(Ega1, 18); \
Eke1 ^= De1; \
Bi = ROL32(Eke1, 5); \
Emi0 ^= Di0; \
Bo = ROL32(Emi0, 7); \
Eso1 ^= Do1; \
Bu = ROL32(Eso1, 28); \
Ama1 = Ba ^((~Be)& Bi ); \
Ame1 = Be ^((~Bi)& Bo ); \
Ami1 = Bi ^((~Bo)& Bu ); \
Amo1 = Bo ^((~Bu)& Ba ); \
Amu1 = Bu ^((~Ba)& Be ); \
\
Ebi1 ^= Di1; \
Ba = ROL32(Ebi1, 31); \
Ego0 ^= Do0; \
Be = ROL32(Ego0, 27); \
Eku0 ^= Du0; \
Bi = ROL32(Eku0, 19); \
Ema0 ^= Da0; \
Bo = ROL32(Ema0, 20); \
Ese1 ^= De1; \
Bu = ROL32(Ese1, 1); \
Asa1 = Ba ^((~Be)& Bi ); \
Ase1 = Be ^((~Bi)& Bo ); \
Asi1 = Bi ^((~Bo)& Bu ); \
Aso1 = Bo ^((~Bu)& Ba ); \
Asu1 = Bu ^((~Ba)& Be ); \
} \
copyToState(state, A) \
}
#define copyFromState(X, state) \
X##ba0 = state[ 0]; \
X##ba1 = state[ 1]; \
X##be0 = state[ 2]; \
X##be1 = state[ 3]; \
X##bi0 = state[ 4]; \
X##bi1 = state[ 5]; \
X##bo0 = state[ 6]; \
X##bo1 = state[ 7]; \
X##bu0 = state[ 8]; \
X##bu1 = state[ 9]; \
X##ga0 = state[10]; \
X##ga1 = state[11]; \
X##ge0 = state[12]; \
X##ge1 = state[13]; \
X##gi0 = state[14]; \
X##gi1 = state[15]; \
X##go0 = state[16]; \
X##go1 = state[17]; \
X##gu0 = state[18]; \
X##gu1 = state[19]; \
X##ka0 = state[20]; \
X##ka1 = state[21]; \
X##ke0 = state[22]; \
X##ke1 = state[23]; \
X##ki0 = state[24]; \
X##ki1 = state[25]; \
X##ko0 = state[26]; \
X##ko1 = state[27]; \
X##ku0 = state[28]; \
X##ku1 = state[29]; \
X##ma0 = state[30]; \
X##ma1 = state[31]; \
X##me0 = state[32]; \
X##me1 = state[33]; \
X##mi0 = state[34]; \
X##mi1 = state[35]; \
X##mo0 = state[36]; \
X##mo1 = state[37]; \
X##mu0 = state[38]; \
X##mu1 = state[39]; \
X##sa0 = state[40]; \
X##sa1 = state[41]; \
X##se0 = state[42]; \
X##se1 = state[43]; \
X##si0 = state[44]; \
X##si1 = state[45]; \
X##so0 = state[46]; \
X##so1 = state[47]; \
X##su0 = state[48]; \
X##su1 = state[49]; \
#define copyToState(state, X) \
state[ 0] = X##ba0; \
state[ 1] = X##ba1; \
state[ 2] = X##be0; \
state[ 3] = X##be1; \
state[ 4] = X##bi0; \
state[ 5] = X##bi1; \
state[ 6] = X##bo0; \
state[ 7] = X##bo1; \
state[ 8] = X##bu0; \
state[ 9] = X##bu1; \
state[10] = X##ga0; \
state[11] = X##ga1; \
state[12] = X##ge0; \
state[13] = X##ge1; \
state[14] = X##gi0; \
state[15] = X##gi1; \
state[16] = X##go0; \
state[17] = X##go1; \
state[18] = X##gu0; \
state[19] = X##gu1; \
state[20] = X##ka0; \
state[21] = X##ka1; \
state[22] = X##ke0; \
state[23] = X##ke1; \
state[24] = X##ki0; \
state[25] = X##ki1; \
state[26] = X##ko0; \
state[27] = X##ko1; \
state[28] = X##ku0; \
state[29] = X##ku1; \
state[30] = X##ma0; \
state[31] = X##ma1; \
state[32] = X##me0; \
state[33] = X##me1; \
state[34] = X##mi0; \
state[35] = X##mi1; \
state[36] = X##mo0; \
state[37] = X##mo1; \
state[38] = X##mu0; \
state[39] = X##mu1; \
state[40] = X##sa0; \
state[41] = X##sa1; \
state[42] = X##se0; \
state[43] = X##se1; \
state[44] = X##si0; \
state[45] = X##si1; \
state[46] = X##so0; \
state[47] = X##so1; \
state[48] = X##su0; \
state[49] = X##su1; \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifdef UseSchedule
#if (UseSchedule == 1)
#include "KeccakF-1600-32-s1.macros"
#elif (UseSchedule == 2)
#include "KeccakF-1600-32-s2.macros"
#elif (UseSchedule == 3)
#include "KeccakF-1600-32-rvk.macros"
#else
#error "This schedule is not supported."
#endif
#else
#include "KeccakF-1600-32-s1.macros"
#endif

View File

@ -1,123 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "KeccakF-1600-interface.h"
#include "KeccakSponge.h"
#include <string.h>
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long int UINT64;
void KeccakPermutationOnWordsAfterXoring_ARM_asm(UINT32 *state, const UINT8 *input, int laneCount);
void KeccakInitialize( void )
{
}
void KeccakInitializeState(unsigned char *state)
{
memset(state, 0, KeccakPermutationSizeInBytes);
}
void KeccakPermutation(unsigned char *state)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, 0, 0);
}
#ifdef ProvideFast576
void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, 9);
}
#endif
#ifdef ProvideFast832
void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, 13);
}
#endif
#ifdef ProvideFast1024
void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, 16);
}
#endif
#ifdef ProvideFast1088
void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, 17);
}
#endif
#ifdef ProvideFast1152
void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, 18);
}
#endif
#ifdef ProvideFast1344
void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, 21);
}
#endif
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
{
KeccakPermutationOnWordsAfterXoring_ARM_asm((UINT32*)state, data, laneCount);
}
// Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
UINT64 fromInterleaving(UINT64 x)
{
UINT64 t;
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16);
t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1);
return x;
}
void setInterleavedWordsInto8bytes(UINT8* dest, UINT32* evenAndOdd)
{
((UINT64*)dest)[0] = fromInterleaving(*(UINT64*)evenAndOdd);
}
#define extractLanes(laneCount, state, data) \
{ \
int i; \
for(i=0; i<(laneCount); i++) \
setInterleavedWordsInto8bytes(data+i*8, (UINT32*)state+i*2); \
}
#ifdef ProvideFast1024
void KeccakExtract1024bits(const unsigned char *state, unsigned char *data)
{
extractLanes(16, state, data)
}
#endif
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
{
extractLanes(laneCount, state, data)
}

View File

@ -1,653 +0,0 @@
;// The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
;// Michaël Peeters and Gilles Van Assche. For more information, feedback or
;// questions, please refer to our website: http://keccak.noekeon.org/
;//
;// Implementation by Ronny Van Keer,
;// hereby denoted as "the implementer".
;//
;// To the extent possible under law, the implementer has waived all copyright
;// and related or neighboring rights to the source code in this file.
;// http://creativecommons.org/publicdomain/zero/1.0/
PRESERVE8
THUMB
AREA |.text|, CODE, READONLY
;// --- defines
_ba0 equ 0*4
_ba1 equ 1*4
_be0 equ 2*4
_be1 equ 3*4
_bi0 equ 4*4
_bi1 equ 5*4
_bo0 equ 6*4
_bo1 equ 7*4
_bu0 equ 8*4
_bu1 equ 9*4
_ga0 equ 10*4
_ga1 equ 11*4
_ge0 equ 12*4
_ge1 equ 13*4
_gi0 equ 14*4
_gi1 equ 15*4
_go0 equ 16*4
_go1 equ 17*4
_gu0 equ 18*4
_gu1 equ 19*4
_ka0 equ 20*4
_ka1 equ 21*4
_ke0 equ 22*4
_ke1 equ 23*4
_ki0 equ 24*4
_ki1 equ 25*4
_ko0 equ 26*4
_ko1 equ 27*4
_ku0 equ 28*4
_ku1 equ 29*4
_ma0 equ 30*4
_ma1 equ 31*4
_me0 equ 32*4
_me1 equ 33*4
_mi0 equ 34*4
_mi1 equ 35*4
_mo0 equ 36*4
_mo1 equ 37*4
_mu0 equ 38*4
_mu1 equ 39*4
_sa0 equ 40*4
_sa1 equ 41*4
_se0 equ 42*4
_se1 equ 43*4
_si0 equ 44*4
_si1 equ 45*4
_so0 equ 46*4
_so1 equ 47*4
_su0 equ 48*4
_su1 equ 49*4
mDe1 equ 50*4
mDi0 equ 51*4
mDo0 equ 52*4
mDo1 equ 53*4
;// --- macros
MACRO
xor5 $result,$ptr,$b,$g,$k,$m,$s
ldr $result, [$ptr, #$b]
ldr r1, [$ptr, #$g]
ldr r2, [$ptr, #$k]
eor $result, $result, r1
ldr r1, [$ptr, #$m]
eor $result, $result, r2
ldr r2, [$ptr, #$s]
eor $result, $result, r1
eor $result, $result, r2
MEND
MACRO
xorrol $b, $yy, $rr
eor $b, $b, $yy
ror $b, #32-$rr
MEND
MACRO
xandnot $resptr, $resofs, $aa, $bb, $cc
bic r1, $cc, $bb
eor r1, r1, $aa
str r1, [$resptr, #$resofs]
MEND
MACRO
xandnotRC $resptr, $resofs, $aa, $bb, $cc
ldr r1, [r3], #4
bic $cc, $cc, $bb
eor $cc, $cc, r1
eor $cc, $cc, $aa
str $cc, [$resptr, #$resofs]
MEND
EXPORT KeccakPermutationOnWordsAfterXoring_ARM_asm
KeccakPermutationOnWordsAfterXoring_ARM_asm PROC
push {r4-r12,lr}
sub sp,sp,#4*(50+4)
movs r9, r2
beq interleaveDone
mov r8,r0
interleaveLoop
ldr r4, [r1], #4
ldr r5, [r1], #4
ldrd r6, r7, [r8]
;// Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
and r3,r4,#0x55555555
orr r3,r3,r3, LSR #1
and r3,r3,#0x33333333
orr r3,r3,r3, LSR #2
and r3,r3,#0x0F0F0F0F
orr r3,r3,r3, LSR #4
and r3,r3,#0x00FF00FF
bfi r3,r3,#8, #8
eor r6,r6,r3, LSR #8
and r3,r5,#0x55555555
orr r3,r3,r3, LSR #1
and r3,r3,#0x33333333
orr r3,r3,r3, LSR #2
and r3,r3,#0x0F0F0F0F
orr r3,r3,r3, LSR #4
and r3,r3,#0x00FF00FF
orr r3,r3,r3, LSR #8
eor r6,r6,r3, LSL #16
and r3,r4,#0xAAAAAAAA
orr r3,r3,r3, LSL #1
and r3,r3,#0xCCCCCCCC
orr r3,r3,r3, LSL #2
and r3,r3,#0xF0F0F0F0
orr r3,r3,r3, LSL #4
and r3,r3,#0xFF00FF00
orr r3,r3,r3, LSL #8
eor r7,r7,r3, LSR #16
and r3,r5,#0xAAAAAAAA
orr r3,r3,r3, LSL #1
and r3,r3,#0xCCCCCCCC
orr r3,r3,r3, LSL #2
and r3,r3,#0xF0F0F0F0
orr r3,r3,r3, LSL #4
and r3,r3,#0xFF00FF00
orr r3,r3,r3, LSL #8
bfc r3, #0, #16
eor r7,r7,r3
strd r6,r7,[r8], #8
subs r9,r9,#1
bne interleaveLoop
interleaveDone
ldr r3, =KeccakF1600RoundConstantsWithTerminator
b roundLoop ;//jump over the table
LTORG
ALIGN
KeccakF1600RoundConstantsWithTerminator
;// 0 1
dcd 0x00000001, 0x00000000
dcd 0x00000000, 0x00000089
dcd 0x00000000, 0x8000008b
dcd 0x00000000, 0x80008080
dcd 0x00000001, 0x0000008b
dcd 0x00000001, 0x00008000
dcd 0x00000001, 0x80008088
dcd 0x00000001, 0x80000082
dcd 0x00000000, 0x0000000b
dcd 0x00000000, 0x0000000a
dcd 0x00000001, 0x00008082
dcd 0x00000000, 0x00008003
dcd 0x00000001, 0x0000808b
dcd 0x00000001, 0x8000000b
dcd 0x00000001, 0x8000008a
dcd 0x00000001, 0x80000081
dcd 0x00000000, 0x80000081
dcd 0x00000000, 0x80000008
dcd 0x00000000, 0x00000083
dcd 0x00000000, 0x80008003
dcd 0x00000001, 0x80008088
dcd 0x00000000, 0x80000088
dcd 0x00000001, 0x00008000
dcd 0x00000000, 0x80008082
dcd 0xFFFFFFFF ;//terminator
roundLoop
;//prepTheta A
xor5 r10, r0,_bu0, _gu0, _ku0, _mu0, _su0
xor5 r6, r0,_be1, _ge1, _ke1, _me1, _se1
eor r5, r10, r6, ROR #31
xor5 r11, r0,_bu1, _gu1, _ku1, _mu1, _su1
xor5 r7, r0,_be0, _ge0, _ke0, _me0, _se0
eor r4, r11, r7
xor5 r8, r0,_bi0, _gi0, _ki0, _mi0, _si0
eor r1, r8, r11, ROR #31
str r1, [sp, #mDo0]
xor5 r9, r0,_bi1, _gi1, _ki1, _mi1, _si1
eor r1, r9, r10
str r1, [sp, #mDo1]
xor5 r10, r0,_ba0, _ga0, _ka0, _ma0, _sa0
eor lr, r10, r9, ROR #31
xor5 r11, r0,_ba1, _ga1, _ka1, _ma1, _sa1
eor r1, r11, r8
str r1, [sp, #mDe1]
xor5 r9, r0,_bo1, _go1, _ko1, _mo1, _so1
eor r1, r7, r9, ROR #31
str r1, [sp, #mDi0]
xor5 r8, r0,_bo0, _go0, _ko0, _mo0, _so0
eor r2, r6, r8
eor r7, r8, r11, ROR #31
eor r6, r9, r10
;//thetaRhoPiChiIota 0, in A, out E
ldr r8, [r0, #_ba0]
ldr r9, [r0, #_ge0]
ldr r10, [r0, #_ki1]
ldr r11, [r0, #_mo1]
ldr r12, [r0, #_su0]
ldr r1, [sp, #mDo1]
eor r8, r8, r5
xorrol r9, lr, 22
xorrol r10, r2, 22
xorrol r11, r1, 11
xorrol r12, r7, 7
xandnot sp, _be0, r9, r10, r11
xandnot sp, _bi0, r10, r11, r12
xandnot sp, _bo0, r11, r12, r8
xandnot sp, _bu0, r12, r8, r9
xandnotRC sp, _ba0, r8, r9, r10
ldr r8, [r0, #_bo0]
ldr r1, [sp, #mDo0]
ldr r9, [r0, #_gu0]
xorrol r8, r1, 14
ldr r1, [sp, #mDe1]
ldr r10, [r0, #_ka1]
ldr r11, [r0, #_me1]
ldr r12, [r0, #_si1]
xorrol r9, r7, 10
xorrol r10, r4, 2
xorrol r11, r1, 23
xorrol r12, r2, 31
xandnot sp, _ga0, r8, r9, r10
xandnot sp, _ge0, r9, r10, r11
xandnot sp, _gi0, r10, r11, r12
xandnot sp, _go0, r11, r12, r8
xandnot sp, _gu0, r12, r8, r9
ldr r8, [r0, #_be1]
ldr r1, [sp, #mDe1]
ldr r9, [r0, #_gi0]
xorrol r8, r1, 1
ldr r1, [sp, #mDi0]
ldr r10, [r0, #_ko1]
xorrol r9, r1, 3
ldr r1, [sp, #mDo1]
ldr r11, [r0, #_mu0]
ldr r12, [r0, #_sa0]
xorrol r10, r1, 13
xorrol r11, r7, 4
xorrol r12, r5, 9
xandnot sp, _ka0, r8, r9, r10
xandnot sp, _ke0, r9, r10, r11
xandnot sp, _ki0, r10, r11, r12
xandnot sp, _ko0, r11, r12, r8
xandnot sp, _ku0, r12, r8, r9
ldr r8, [r0, #_bu1]
ldr r9, [r0, #_ga0]
ldr r10, [r0, #_ke0]
ldr r11, [r0, #_mi1]
ldr r12, [r0, #_so0]
ldr r1, [sp, #mDo0]
xorrol r8, r6, 14
xorrol r9, r5, 18
xorrol r10, lr, 5
xorrol r11, r2, 8
xorrol r12, r1, 28
xandnot sp, _ma0, r8, r9, r10
xandnot sp, _me0, r9, r10, r11
xandnot sp, _mi0, r10, r11, r12
xandnot sp, _mo0, r11, r12, r8
xandnot sp, _mu0, r12, r8, r9
ldr r1, [sp, #mDi0]
ldr r8, [r0, #_bi0]
ldr r9, [r0, #_go1]
xorrol r8, r1, 31
ldr r1, [sp, #mDo1]
ldr r10, [r0, #_ku1]
xorrol r9, r1, 28
ldr r11, [r0, #_ma1]
ldr r12, [r0, #_se0]
xorrol r10, r6, 20
xorrol r11, r4, 21
xorrol r12, lr, 1
xandnot sp, _sa0, r8, r9, r10
xandnot sp, _se0, r9, r10, r11
xandnot sp, _si0, r10, r11, r12
xandnot sp, _so0, r11, r12, r8
xandnot sp, _su0, r12, r8, r9
;// thetaRhoPiChiIota 1, in A, out E
ldr r1, [sp, #mDe1]
ldr r9, [r0, #_ge1]
ldr r8, [r0, #_ba1]
xorrol r9, r1, 22
ldr r1, [sp, #mDi0]
ldr r10, [r0, #_ki0]
eor r8, r8, r4
xorrol r10, r1, 21
ldr r1, [sp, #mDo0]
ldr r11, [r0, #_mo0]
ldr r12, [r0, #_su1]
xorrol r11, r1, 10
xorrol r12, r6, 7
xandnot sp, _be1, r9, r10, r11
xandnot sp, _bi1, r10, r11, r12
xandnot sp, _bo1, r11, r12, r8
xandnot sp, _bu1, r12, r8, r9
xandnotRC sp, _ba1, r8, r9, r10
ldr r1, [sp, #mDo1]
ldr r8, [r0, #_bo1]
ldr r12, [r0, #_si0]
xorrol r8, r1, 14
ldr r1, [sp, #mDi0]
ldr r9, [r0, #_gu1]
xorrol r12, r1, 30
ldr r10, [r0, #_ka0]
ldr r11, [r0, #_me0]
xorrol r9, r6, 10
xorrol r10, r5, 1
xorrol r11, lr, 22
xandnot sp, _ga1, r8, r9, r10
xandnot sp, _ge1, r9, r10, r11
xandnot sp, _gi1, r10, r11, r12
xandnot sp, _go1, r11, r12, r8
xandnot sp, _gu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r10, [r0, #_ko0]
ldr r8, [r0, #_be0]
xorrol r10, r1, 12
ldr r9, [r0, #_gi1]
ldr r11, [r0, #_mu1]
ldr r12, [r0, #_sa1]
eor r8, r8, lr
xorrol r9, r2, 3
xorrol r11, r6, 4
xorrol r12, r4, 9
xandnot sp, _ka1, r8, r9, r10
xandnot sp, _ke1, r9, r10, r11
xandnot sp, _ki1, r10, r11, r12
xandnot sp, _ko1, r11, r12, r8
xandnot sp, _ku1, r12, r8, r9
ldr r1, [sp, #mDe1]
ldr r10, [r0, #_ke1]
ldr r11, [r0, #_mi0]
xorrol r10, r1, 5
ldr r1, [sp, #mDi0]
ldr r12, [r0, #_so1]
xorrol r11, r1, 7
ldr r1, [sp, #mDo1]
ldr r8, [r0, #_bu0]
ldr r9, [r0, #_ga1]
xorrol r8, r7, 13
xorrol r9, r4, 18
xorrol r12, r1, 28
xandnot sp, _ma1, r8, r9, r10
xandnot sp, _me1, r9, r10, r11
xandnot sp, _mi1, r10, r11, r12
xandnot sp, _mo1, r11, r12, r8
xandnot sp, _mu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r9, [r0, #_go0]
ldr r8, [r0, #_bi1]
xorrol r9, r1, 27
ldr r10, [r0, #_ku0]
ldr r11, [r0, #_ma0]
ldr r12, [r0, #_se1]
ldr r1, [sp, #mDe1]
xorrol r8, r2, 31
xorrol r10, r7, 19
xorrol r11, r5, 20
xorrol r12, r1, 1
xandnot sp, _sa1, r8, r9, r10
xandnot sp, _se1, r9, r10, r11
xandnot sp, _si1, r10, r11, r12
xandnot sp, _so1, r11, r12, r8
xandnot sp, _su1, r12, r8, r9
;//prepTheta E
xor5 r10, sp,_bu0, _gu0, _ku0, _mu0, _su0
xor5 r6, sp,_be1, _ge1, _ke1, _me1, _se1
eor r5, r10, r6, ROR #31
xor5 r11, sp,_bu1, _gu1, _ku1, _mu1, _su1
xor5 r7, sp,_be0, _ge0, _ke0, _me0, _se0
eor r4, r11, r7
xor5 r8, sp,_bi0, _gi0, _ki0, _mi0, _si0
eor r1, r8, r11, ROR #31
str r1, [sp, #mDo0]
xor5 r9, sp,_bi1, _gi1, _ki1, _mi1, _si1
eor r1, r9, r10
str r1, [sp, #mDo1]
xor5 r10, sp,_ba0, _ga0, _ka0, _ma0, _sa0
eor lr, r10, r9, ROR #31
xor5 r11, sp,_ba1, _ga1, _ka1, _ma1, _sa1
eor r1, r11, r8
str r1, [sp, #mDe1]
xor5 r9, sp,_bo1, _go1, _ko1, _mo1, _so1
eor r1, r7, r9, ROR #31
str r1, [sp, #mDi0]
xor5 r8, sp,_bo0, _go0, _ko0, _mo0, _so0
eor r2, r6, r8
eor r7, r8, r11, ROR #31
eor r6, r9, r10
;//thetaRhoPiChiIota 0, in E, out A
ldr r8, [sp, #_ba0]
ldr r9, [sp, #_ge0]
ldr r10, [sp, #_ki1]
ldr r11, [sp, #_mo1]
ldr r12, [sp, #_su0]
ldr r1, [sp, #mDo1]
eor r8, r8, r5
xorrol r9, lr, 22
xorrol r10, r2, 22
xorrol r11, r1, 11
xorrol r12, r7, 7
xandnot r0, _be0, r9, r10, r11
xandnot r0, _bi0, r10, r11, r12
xandnot r0, _bo0, r11, r12, r8
xandnot r0, _bu0, r12, r8, r9
xandnotRC r0, _ba0, r8, r9, r10
ldr r8, [sp, #_bo0]
ldr r1, [sp, #mDo0]
ldr r9, [sp, #_gu0]
xorrol r8, r1, 14
ldr r1, [sp, #mDe1]
ldr r10, [sp, #_ka1]
ldr r11, [sp, #_me1]
ldr r12, [sp, #_si1]
xorrol r9, r7, 10
xorrol r10, r4, 2
xorrol r11, r1, 23
xorrol r12, r2, 31
xandnot r0, _ga0, r8, r9, r10
xandnot r0, _ge0, r9, r10, r11
xandnot r0, _gi0, r10, r11, r12
xandnot r0, _go0, r11, r12, r8
xandnot r0, _gu0, r12, r8, r9
ldr r8, [sp, #_be1]
ldr r1, [sp, #mDe1]
ldr r9, [sp, #_gi0]
xorrol r8, r1, 1
ldr r1, [sp, #mDi0]
ldr r10, [sp, #_ko1]
xorrol r9, r1, 3
ldr r1, [sp, #mDo1]
ldr r11, [sp, #_mu0]
ldr r12, [sp, #_sa0]
xorrol r10, r1, 13
xorrol r11, r7, 4
xorrol r12, r5, 9
xandnot r0, _ka0, r8, r9, r10
xandnot r0, _ke0, r9, r10, r11
xandnot r0, _ki0, r10, r11, r12
xandnot r0, _ko0, r11, r12, r8
xandnot r0, _ku0, r12, r8, r9
ldr r8, [sp, #_bu1]
ldr r9, [sp, #_ga0]
ldr r10, [sp, #_ke0]
ldr r11, [sp, #_mi1]
ldr r12, [sp, #_so0]
ldr r1, [sp, #mDo0]
xorrol r8, r6, 14
xorrol r9, r5, 18
xorrol r10, lr, 5
xorrol r11, r2, 8
xorrol r12, r1, 28
xandnot r0, _ma0, r8, r9, r10
xandnot r0, _me0, r9, r10, r11
xandnot r0, _mi0, r10, r11, r12
xandnot r0, _mo0, r11, r12, r8
xandnot r0, _mu0, r12, r8, r9
ldr r1, [sp, #mDi0]
ldr r8, [sp, #_bi0]
ldr r9, [sp, #_go1]
xorrol r8, r1, 31
ldr r1, [sp, #mDo1]
ldr r10, [sp, #_ku1]
xorrol r9, r1, 28
ldr r11, [sp, #_ma1]
ldr r12, [sp, #_se0]
xorrol r10, r6, 20
xorrol r11, r4, 21
xorrol r12, lr, 1
xandnot r0, _sa0, r8, r9, r10
xandnot r0, _se0, r9, r10, r11
xandnot r0, _si0, r10, r11, r12
xandnot r0, _so0, r11, r12, r8
xandnot r0, _su0, r12, r8, r9
;// thetaRhoPiChiIota 1, in A, out E
ldr r1, [sp, #mDe1]
ldr r9, [sp, #_ge1]
ldr r8, [sp, #_ba1]
xorrol r9, r1, 22
ldr r1, [sp, #mDi0]
ldr r10, [sp, #_ki0]
eor r8, r8, r4
xorrol r10, r1, 21
ldr r1, [sp, #mDo0]
ldr r11, [sp, #_mo0]
ldr r12, [sp, #_su1]
xorrol r11, r1, 10
xorrol r12, r6, 7
xandnot r0, _be1, r9, r10, r11
xandnot r0, _bi1, r10, r11, r12
xandnot r0, _bo1, r11, r12, r8
xandnot r0, _bu1, r12, r8, r9
xandnotRC r0, _ba1, r8, r9, r10
ldr r1, [sp, #mDo1]
ldr r8, [sp, #_bo1]
ldr r12, [sp, #_si0]
xorrol r8, r1, 14
ldr r1, [sp, #mDi0]
ldr r9, [sp, #_gu1]
xorrol r12, r1, 30
ldr r10, [sp, #_ka0]
ldr r11, [sp, #_me0]
xorrol r9, r6, 10
xorrol r10, r5, 1
xorrol r11, lr, 22
xandnot r0, _ga1, r8, r9, r10
xandnot r0, _ge1, r9, r10, r11
xandnot r0, _gi1, r10, r11, r12
xandnot r0, _go1, r11, r12, r8
xandnot r0, _gu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r10, [sp, #_ko0]
ldr r8, [sp, #_be0]
xorrol r10, r1, 12
ldr r9, [sp, #_gi1]
ldr r11, [sp, #_mu1]
ldr r12, [sp, #_sa1]
eor r8, r8, lr
xorrol r9, r2, 3
xorrol r11, r6, 4
xorrol r12, r4, 9
xandnot r0, _ka1, r8, r9, r10
xandnot r0, _ke1, r9, r10, r11
xandnot r0, _ki1, r10, r11, r12
xandnot r0, _ko1, r11, r12, r8
xandnot r0, _ku1, r12, r8, r9
ldr r1, [sp, #mDe1]
ldr r10, [sp, #_ke1]
ldr r11, [sp, #_mi0]
xorrol r10, r1, 5
ldr r1, [sp, #mDi0]
ldr r12, [sp, #_so1]
xorrol r11, r1, 7
ldr r1, [sp, #mDo1]
ldr r8, [sp, #_bu0]
ldr r9, [sp, #_ga1]
xorrol r8, r7, 13
xorrol r9, r4, 18
xorrol r12, r1, 28
xandnot r0, _ma1, r8, r9, r10
xandnot r0, _me1, r9, r10, r11
xandnot r0, _mi1, r10, r11, r12
xandnot r0, _mo1, r11, r12, r8
xandnot r0, _mu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r9, [sp, #_go0]
ldr r8, [sp, #_bi1]
xorrol r9, r1, 27
ldr r10, [sp, #_ku0]
ldr r11, [sp, #_ma0]
ldr r12, [sp, #_se1]
ldr r1, [sp, #mDe1]
xorrol r8, r2, 31
xorrol r10, r7, 19
xorrol r11, r5, 20
xorrol r12, r1, 1
xandnot r0, _sa1, r8, r9, r10
xandnot r0, _se1, r9, r10, r11
xandnot r0, _si1, r10, r11, r12
xandnot r0, _so1, r11, r12, r8
ldr r10, [r3]
xandnot r0, _su1, r12, r8, r9
cmp r10, #0xFFFFFFFF
bne roundLoop
add sp,sp,#4*(50+4)
pop {r4-r12,pc}
ENDP
ALIGN
END

View File

@ -1,686 +0,0 @@
@ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
@ Michaël Peeters and Gilles Van Assche. For more information, feedback or
@ questions, please refer to our website: http://keccak.noekeon.org/
@
@ Implementation by Ronny Van Keer,
@ hereby denoted as "the implementer".
@
@ To the extent possible under law, the implementer has waived all copyright
@ and related or neighboring rights to the source code in this file.
@ http://creativecommons.org/publicdomain/zero/1.0/
@ This file was created from a .asm file
@ using the ads2gas.pl script.
.equ DO1STROUNDING, 0
@ PRESERVE8
@ THUMB
.syntax unified
.cpu cortex-m3
.thumb
@// --- defines
.equ _ba0 , 0*4
.equ _ba1 , 1*4
.equ _be0 , 2*4
.equ _be1 , 3*4
.equ _bi0 , 4*4
.equ _bi1 , 5*4
.equ _bo0 , 6*4
.equ _bo1 , 7*4
.equ _bu0 , 8*4
.equ _bu1 , 9*4
.equ _ga0 , 10*4
.equ _ga1 , 11*4
.equ _ge0 , 12*4
.equ _ge1 , 13*4
.equ _gi0 , 14*4
.equ _gi1 , 15*4
.equ _go0 , 16*4
.equ _go1 , 17*4
.equ _gu0 , 18*4
.equ _gu1 , 19*4
.equ _ka0 , 20*4
.equ _ka1 , 21*4
.equ _ke0 , 22*4
.equ _ke1 , 23*4
.equ _ki0 , 24*4
.equ _ki1 , 25*4
.equ _ko0 , 26*4
.equ _ko1 , 27*4
.equ _ku0 , 28*4
.equ _ku1 , 29*4
.equ _ma0 , 30*4
.equ _ma1 , 31*4
.equ _me0 , 32*4
.equ _me1 , 33*4
.equ _mi0 , 34*4
.equ _mi1 , 35*4
.equ _mo0 , 36*4
.equ _mo1 , 37*4
.equ _mu0 , 38*4
.equ _mu1 , 39*4
.equ _sa0 , 40*4
.equ _sa1 , 41*4
.equ _se0 , 42*4
.equ _se1 , 43*4
.equ _si0 , 44*4
.equ _si1 , 45*4
.equ _so0 , 46*4
.equ _so1 , 47*4
.equ _su0 , 48*4
.equ _su1 , 49*4
.equ mDe1 , 50*4
.equ mDi0 , 51*4
.equ mDo0 , 52*4
.equ mDo1 , 53*4
@// --- macros
.macro xor5 result,ptr,b,g,k,m,s
ldr \result, [\ptr, #\b]
ldr r1, [\ptr, #\g]
ldr r2, [\ptr, #\k]
eor \result, \result, r1
ldr r1, [\ptr, #\m]
eor \result, \result, r2
ldr r2, [\ptr, #\s]
eor \result, \result, r1
eor \result, \result, r2
.endm
.macro xorrol b, yy, rr
eor \b, \b, \yy
ror \b, #32-\rr
.endm
.macro xandnot resptr, resofs, aa, bb, cc
bic r1, \cc, \bb
eor r1, r1, \aa
str r1, [\resptr, #\resofs]
.endm
.macro xandnotRC resptr, resofs, aa, bb, cc
ldr r1, [r3], #4
bic \cc, \cc, \bb
eor \cc, \cc, r1
eor \cc, \cc, \aa
str \cc, [\resptr, #\resofs]
.endm
.size KeccakPermutationOnWords, .-KeccakPermutationOnWords
.align 2
.global KeccakPermutationOnWordsAfterXoring_ARM_asm
.thumb
.thumb_func
.type KeccakPermutationOnWordsAfterXoring_ARM_asm, %function
KeccakPermutationOnWordsAfterXoring_ARM_asm:
@ args = 0, pretend = 0, frame = 408
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
push {r4-r12,lr}
sub sp,sp,#4*(50+4)
movs r9, r2
beq interleaveDone
mov r8,r0
interleaveLoop:
ldr r4, [r1], #4
ldr r5, [r1], #4
ldrd r6, r7, [r8]
@// Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
and r3,r4,#0x55555555
orr r3,r3,r3, LSR #1
and r3,r3,#0x33333333
orr r3,r3,r3, LSR #2
and r3,r3,#0x0F0F0F0F
orr r3,r3,r3, LSR #4
and r3,r3,#0x00FF00FF
bfi r3,r3,#8, #8
eor r6,r6,r3, LSR #8
and r3,r5,#0x55555555
orr r3,r3,r3, LSR #1
and r3,r3,#0x33333333
orr r3,r3,r3, LSR #2
and r3,r3,#0x0F0F0F0F
orr r3,r3,r3, LSR #4
and r3,r3,#0x00FF00FF
orr r3,r3,r3, LSR #8
eor r6,r6,r3, LSL #16
and r3,r4,#0xAAAAAAAA
orr r3,r3,r3, LSL #1
and r3,r3,#0xCCCCCCCC
orr r3,r3,r3, LSL #2
and r3,r3,#0xF0F0F0F0
orr r3,r3,r3, LSL #4
and r3,r3,#0xFF00FF00
orr r3,r3,r3, LSL #8
eor r7,r7,r3, LSR #16
and r3,r5,#0xAAAAAAAA
orr r3,r3,r3, LSL #1
and r3,r3,#0xCCCCCCCC
orr r3,r3,r3, LSL #2
and r3,r3,#0xF0F0F0F0
orr r3,r3,r3, LSL #4
and r3,r3,#0xFF00FF00
orr r3,r3,r3, LSL #8
bfc r3, #0, #16
eor r7,r7,r3
strd r6,r7,[r8], #8
subs r9,r9,#1
bne interleaveLoop
interleaveDone:
ldr r3, =KeccakF1600RoundConstantsWithTerminator
b roundLoop @//jump over the table
.ltorg
@ ALIGN
KeccakF1600RoundConstantsWithTerminator:
@// 0 1
.word 0x00000001
.word 0x00000000
.word 0x00000000
.word 0x00000089
.word 0x00000000
.word 0x8000008b
.word 0x00000000
.word 0x80008080
.word 0x00000001
.word 0x0000008b
.word 0x00000001
.word 0x00008000
.word 0x00000001
.word 0x80008088
.word 0x00000001
.word 0x80000082
.word 0x00000000
.word 0x0000000b
.word 0x00000000
.word 0x0000000a
.word 0x00000001
.word 0x00008082
.word 0x00000000
.word 0x00008003
.word 0x00000001
.word 0x0000808b
.word 0x00000001
.word 0x8000000b
.word 0x00000001
.word 0x8000008a
.word 0x00000001
.word 0x80000081
.word 0x00000000
.word 0x80000081
.word 0x00000000
.word 0x80000008
.word 0x00000000
.word 0x00000083
.word 0x00000000
.word 0x80008003
.word 0x00000001
.word 0x80008088
.word 0x00000000
.word 0x80000088
.word 0x00000001
.word 0x00008000
.word 0x00000000
.word 0x80008082
.word 0xFFFFFFFF @//terminator
roundLoop:
@//prepTheta A
xor5 r10, r0,_bu0, _gu0, _ku0, _mu0, _su0
xor5 r6, r0,_be1, _ge1, _ke1, _me1, _se1
eor r5, r10, r6, ROR #31
xor5 r11, r0,_bu1, _gu1, _ku1, _mu1, _su1
xor5 r7, r0,_be0, _ge0, _ke0, _me0, _se0
eor r4, r11, r7
xor5 r8, r0,_bi0, _gi0, _ki0, _mi0, _si0
eor r1, r8, r11, ROR #31
str r1, [sp, #mDo0]
xor5 r9, r0,_bi1, _gi1, _ki1, _mi1, _si1
eor r1, r9, r10
str r1, [sp, #mDo1]
xor5 r10, r0,_ba0, _ga0, _ka0, _ma0, _sa0
eor lr, r10, r9, ROR #31
xor5 r11, r0,_ba1, _ga1, _ka1, _ma1, _sa1
eor r1, r11, r8
str r1, [sp, #mDe1]
xor5 r9, r0,_bo1, _go1, _ko1, _mo1, _so1
eor r1, r7, r9, ROR #31
str r1, [sp, #mDi0]
xor5 r8, r0,_bo0, _go0, _ko0, _mo0, _so0
eor r2, r6, r8
eor r7, r8, r11, ROR #31
eor r6, r9, r10
@//thetaRhoPiChiIota 0, in A, out E
ldr r8, [r0, #_ba0]
ldr r9, [r0, #_ge0]
ldr r10, [r0, #_ki1]
ldr r11, [r0, #_mo1]
ldr r12, [r0, #_su0]
ldr r1, [sp, #mDo1]
eor r8, r8, r5
xorrol r9, lr, 22
xorrol r10, r2, 22
xorrol r11, r1, 11
xorrol r12, r7, 7
xandnot sp, _be0, r9, r10, r11
xandnot sp, _bi0, r10, r11, r12
xandnot sp, _bo0, r11, r12, r8
xandnot sp, _bu0, r12, r8, r9
xandnotRC sp, _ba0, r8, r9, r10
ldr r8, [r0, #_bo0]
ldr r1, [sp, #mDo0]
ldr r9, [r0, #_gu0]
xorrol r8, r1, 14
ldr r1, [sp, #mDe1]
ldr r10, [r0, #_ka1]
ldr r11, [r0, #_me1]
ldr r12, [r0, #_si1]
xorrol r9, r7, 10
xorrol r10, r4, 2
xorrol r11, r1, 23
xorrol r12, r2, 31
xandnot sp, _ga0, r8, r9, r10
xandnot sp, _ge0, r9, r10, r11
xandnot sp, _gi0, r10, r11, r12
xandnot sp, _go0, r11, r12, r8
xandnot sp, _gu0, r12, r8, r9
ldr r8, [r0, #_be1]
ldr r1, [sp, #mDe1]
ldr r9, [r0, #_gi0]
xorrol r8, r1, 1
ldr r1, [sp, #mDi0]
ldr r10, [r0, #_ko1]
xorrol r9, r1, 3
ldr r1, [sp, #mDo1]
ldr r11, [r0, #_mu0]
ldr r12, [r0, #_sa0]
xorrol r10, r1, 13
xorrol r11, r7, 4
xorrol r12, r5, 9
xandnot sp, _ka0, r8, r9, r10
xandnot sp, _ke0, r9, r10, r11
xandnot sp, _ki0, r10, r11, r12
xandnot sp, _ko0, r11, r12, r8
xandnot sp, _ku0, r12, r8, r9
ldr r8, [r0, #_bu1]
ldr r9, [r0, #_ga0]
ldr r10, [r0, #_ke0]
ldr r11, [r0, #_mi1]
ldr r12, [r0, #_so0]
ldr r1, [sp, #mDo0]
xorrol r8, r6, 14
xorrol r9, r5, 18
xorrol r10, lr, 5
xorrol r11, r2, 8
xorrol r12, r1, 28
xandnot sp, _ma0, r8, r9, r10
xandnot sp, _me0, r9, r10, r11
xandnot sp, _mi0, r10, r11, r12
xandnot sp, _mo0, r11, r12, r8
xandnot sp, _mu0, r12, r8, r9
ldr r1, [sp, #mDi0]
ldr r8, [r0, #_bi0]
ldr r9, [r0, #_go1]
xorrol r8, r1, 31
ldr r1, [sp, #mDo1]
ldr r10, [r0, #_ku1]
xorrol r9, r1, 28
ldr r11, [r0, #_ma1]
ldr r12, [r0, #_se0]
xorrol r10, r6, 20
xorrol r11, r4, 21
xorrol r12, lr, 1
xandnot sp, _sa0, r8, r9, r10
xandnot sp, _se0, r9, r10, r11
xandnot sp, _si0, r10, r11, r12
xandnot sp, _so0, r11, r12, r8
xandnot sp, _su0, r12, r8, r9
@// thetaRhoPiChiIota 1, in A, out E
ldr r1, [sp, #mDe1]
ldr r9, [r0, #_ge1]
ldr r8, [r0, #_ba1]
xorrol r9, r1, 22
ldr r1, [sp, #mDi0]
ldr r10, [r0, #_ki0]
eor r8, r8, r4
xorrol r10, r1, 21
ldr r1, [sp, #mDo0]
ldr r11, [r0, #_mo0]
ldr r12, [r0, #_su1]
xorrol r11, r1, 10
xorrol r12, r6, 7
xandnot sp, _be1, r9, r10, r11
xandnot sp, _bi1, r10, r11, r12
xandnot sp, _bo1, r11, r12, r8
xandnot sp, _bu1, r12, r8, r9
xandnotRC sp, _ba1, r8, r9, r10
ldr r1, [sp, #mDo1]
ldr r8, [r0, #_bo1]
ldr r12, [r0, #_si0]
xorrol r8, r1, 14
ldr r1, [sp, #mDi0]
ldr r9, [r0, #_gu1]
xorrol r12, r1, 30
ldr r10, [r0, #_ka0]
ldr r11, [r0, #_me0]
xorrol r9, r6, 10
xorrol r10, r5, 1
xorrol r11, lr, 22
xandnot sp, _ga1, r8, r9, r10
xandnot sp, _ge1, r9, r10, r11
xandnot sp, _gi1, r10, r11, r12
xandnot sp, _go1, r11, r12, r8
xandnot sp, _gu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r10, [r0, #_ko0]
ldr r8, [r0, #_be0]
xorrol r10, r1, 12
ldr r9, [r0, #_gi1]
ldr r11, [r0, #_mu1]
ldr r12, [r0, #_sa1]
eor r8, r8, lr
xorrol r9, r2, 3
xorrol r11, r6, 4
xorrol r12, r4, 9
xandnot sp, _ka1, r8, r9, r10
xandnot sp, _ke1, r9, r10, r11
xandnot sp, _ki1, r10, r11, r12
xandnot sp, _ko1, r11, r12, r8
xandnot sp, _ku1, r12, r8, r9
ldr r1, [sp, #mDe1]
ldr r10, [r0, #_ke1]
ldr r11, [r0, #_mi0]
xorrol r10, r1, 5
ldr r1, [sp, #mDi0]
ldr r12, [r0, #_so1]
xorrol r11, r1, 7
ldr r1, [sp, #mDo1]
ldr r8, [r0, #_bu0]
ldr r9, [r0, #_ga1]
xorrol r8, r7, 13
xorrol r9, r4, 18
xorrol r12, r1, 28
xandnot sp, _ma1, r8, r9, r10
xandnot sp, _me1, r9, r10, r11
xandnot sp, _mi1, r10, r11, r12
xandnot sp, _mo1, r11, r12, r8
xandnot sp, _mu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r9, [r0, #_go0]
ldr r8, [r0, #_bi1]
xorrol r9, r1, 27
ldr r10, [r0, #_ku0]
ldr r11, [r0, #_ma0]
ldr r12, [r0, #_se1]
ldr r1, [sp, #mDe1]
xorrol r8, r2, 31
xorrol r10, r7, 19
xorrol r11, r5, 20
xorrol r12, r1, 1
xandnot sp, _sa1, r8, r9, r10
xandnot sp, _se1, r9, r10, r11
xandnot sp, _si1, r10, r11, r12
xandnot sp, _so1, r11, r12, r8
xandnot sp, _su1, r12, r8, r9
@//prepTheta E
xor5 r10, sp,_bu0, _gu0, _ku0, _mu0, _su0
xor5 r6, sp,_be1, _ge1, _ke1, _me1, _se1
eor r5, r10, r6, ROR #31
xor5 r11, sp,_bu1, _gu1, _ku1, _mu1, _su1
xor5 r7, sp,_be0, _ge0, _ke0, _me0, _se0
eor r4, r11, r7
xor5 r8, sp,_bi0, _gi0, _ki0, _mi0, _si0
eor r1, r8, r11, ROR #31
str r1, [sp, #mDo0]
xor5 r9, sp,_bi1, _gi1, _ki1, _mi1, _si1
eor r1, r9, r10
str r1, [sp, #mDo1]
xor5 r10, sp,_ba0, _ga0, _ka0, _ma0, _sa0
eor lr, r10, r9, ROR #31
xor5 r11, sp,_ba1, _ga1, _ka1, _ma1, _sa1
eor r1, r11, r8
str r1, [sp, #mDe1]
xor5 r9, sp,_bo1, _go1, _ko1, _mo1, _so1
eor r1, r7, r9, ROR #31
str r1, [sp, #mDi0]
xor5 r8, sp,_bo0, _go0, _ko0, _mo0, _so0
eor r2, r6, r8
eor r7, r8, r11, ROR #31
eor r6, r9, r10
@//thetaRhoPiChiIota 0, in E, out A
ldr r8, [sp, #_ba0]
ldr r9, [sp, #_ge0]
ldr r10, [sp, #_ki1]
ldr r11, [sp, #_mo1]
ldr r12, [sp, #_su0]
ldr r1, [sp, #mDo1]
eor r8, r8, r5
xorrol r9, lr, 22
xorrol r10, r2, 22
xorrol r11, r1, 11
xorrol r12, r7, 7
xandnot r0, _be0, r9, r10, r11
xandnot r0, _bi0, r10, r11, r12
xandnot r0, _bo0, r11, r12, r8
xandnot r0, _bu0, r12, r8, r9
xandnotRC r0, _ba0, r8, r9, r10
ldr r8, [sp, #_bo0]
ldr r1, [sp, #mDo0]
ldr r9, [sp, #_gu0]
xorrol r8, r1, 14
ldr r1, [sp, #mDe1]
ldr r10, [sp, #_ka1]
ldr r11, [sp, #_me1]
ldr r12, [sp, #_si1]
xorrol r9, r7, 10
xorrol r10, r4, 2
xorrol r11, r1, 23
xorrol r12, r2, 31
xandnot r0, _ga0, r8, r9, r10
xandnot r0, _ge0, r9, r10, r11
xandnot r0, _gi0, r10, r11, r12
xandnot r0, _go0, r11, r12, r8
xandnot r0, _gu0, r12, r8, r9
ldr r8, [sp, #_be1]
ldr r1, [sp, #mDe1]
ldr r9, [sp, #_gi0]
xorrol r8, r1, 1
ldr r1, [sp, #mDi0]
ldr r10, [sp, #_ko1]
xorrol r9, r1, 3
ldr r1, [sp, #mDo1]
ldr r11, [sp, #_mu0]
ldr r12, [sp, #_sa0]
xorrol r10, r1, 13
xorrol r11, r7, 4
xorrol r12, r5, 9
xandnot r0, _ka0, r8, r9, r10
xandnot r0, _ke0, r9, r10, r11
xandnot r0, _ki0, r10, r11, r12
xandnot r0, _ko0, r11, r12, r8
xandnot r0, _ku0, r12, r8, r9
ldr r8, [sp, #_bu1]
ldr r9, [sp, #_ga0]
ldr r10, [sp, #_ke0]
ldr r11, [sp, #_mi1]
ldr r12, [sp, #_so0]
ldr r1, [sp, #mDo0]
xorrol r8, r6, 14
xorrol r9, r5, 18
xorrol r10, lr, 5
xorrol r11, r2, 8
xorrol r12, r1, 28
xandnot r0, _ma0, r8, r9, r10
xandnot r0, _me0, r9, r10, r11
xandnot r0, _mi0, r10, r11, r12
xandnot r0, _mo0, r11, r12, r8
xandnot r0, _mu0, r12, r8, r9
ldr r1, [sp, #mDi0]
ldr r8, [sp, #_bi0]
ldr r9, [sp, #_go1]
xorrol r8, r1, 31
ldr r1, [sp, #mDo1]
ldr r10, [sp, #_ku1]
xorrol r9, r1, 28
ldr r11, [sp, #_ma1]
ldr r12, [sp, #_se0]
xorrol r10, r6, 20
xorrol r11, r4, 21
xorrol r12, lr, 1
xandnot r0, _sa0, r8, r9, r10
xandnot r0, _se0, r9, r10, r11
xandnot r0, _si0, r10, r11, r12
xandnot r0, _so0, r11, r12, r8
xandnot r0, _su0, r12, r8, r9
@// thetaRhoPiChiIota 1, in A, out E
ldr r1, [sp, #mDe1]
ldr r9, [sp, #_ge1]
ldr r8, [sp, #_ba1]
xorrol r9, r1, 22
ldr r1, [sp, #mDi0]
ldr r10, [sp, #_ki0]
eor r8, r8, r4
xorrol r10, r1, 21
ldr r1, [sp, #mDo0]
ldr r11, [sp, #_mo0]
ldr r12, [sp, #_su1]
xorrol r11, r1, 10
xorrol r12, r6, 7
xandnot r0, _be1, r9, r10, r11
xandnot r0, _bi1, r10, r11, r12
xandnot r0, _bo1, r11, r12, r8
xandnot r0, _bu1, r12, r8, r9
xandnotRC r0, _ba1, r8, r9, r10
ldr r1, [sp, #mDo1]
ldr r8, [sp, #_bo1]
ldr r12, [sp, #_si0]
xorrol r8, r1, 14
ldr r1, [sp, #mDi0]
ldr r9, [sp, #_gu1]
xorrol r12, r1, 30
ldr r10, [sp, #_ka0]
ldr r11, [sp, #_me0]
xorrol r9, r6, 10
xorrol r10, r5, 1
xorrol r11, lr, 22
xandnot r0, _ga1, r8, r9, r10
xandnot r0, _ge1, r9, r10, r11
xandnot r0, _gi1, r10, r11, r12
xandnot r0, _go1, r11, r12, r8
xandnot r0, _gu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r10, [sp, #_ko0]
ldr r8, [sp, #_be0]
xorrol r10, r1, 12
ldr r9, [sp, #_gi1]
ldr r11, [sp, #_mu1]
ldr r12, [sp, #_sa1]
eor r8, r8, lr
xorrol r9, r2, 3
xorrol r11, r6, 4
xorrol r12, r4, 9
xandnot r0, _ka1, r8, r9, r10
xandnot r0, _ke1, r9, r10, r11
xandnot r0, _ki1, r10, r11, r12
xandnot r0, _ko1, r11, r12, r8
xandnot r0, _ku1, r12, r8, r9
ldr r1, [sp, #mDe1]
ldr r10, [sp, #_ke1]
ldr r11, [sp, #_mi0]
xorrol r10, r1, 5
ldr r1, [sp, #mDi0]
ldr r12, [sp, #_so1]
xorrol r11, r1, 7
ldr r1, [sp, #mDo1]
ldr r8, [sp, #_bu0]
ldr r9, [sp, #_ga1]
xorrol r8, r7, 13
xorrol r9, r4, 18
xorrol r12, r1, 28
xandnot r0, _ma1, r8, r9, r10
xandnot r0, _me1, r9, r10, r11
xandnot r0, _mi1, r10, r11, r12
xandnot r0, _mo1, r11, r12, r8
xandnot r0, _mu1, r12, r8, r9
ldr r1, [sp, #mDo0]
ldr r9, [sp, #_go0]
ldr r8, [sp, #_bi1]
xorrol r9, r1, 27
ldr r10, [sp, #_ku0]
ldr r11, [sp, #_ma0]
ldr r12, [sp, #_se1]
ldr r1, [sp, #mDe1]
xorrol r8, r2, 31
xorrol r10, r7, 19
xorrol r11, r5, 20
xorrol r12, r1, 1
xandnot r0, _sa1, r8, r9, r10
xandnot r0, _se1, r9, r10, r11
xandnot r0, _si1, r10, r11, r12
xandnot r0, _so1, r11, r12, r8
ldr r10, [r3]
xandnot r0, _su1, r12, r8, r9
cmp r10, #0xFFFFFFFF
bne roundLoop
add sp,sp,#4*(50+4)
pop {r4-r12,pc}
@
@ ALIGN

View File

@ -1,163 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <string.h>
#include <avr/pgmspace.h>
#include "AVR8-rotate64.h"
typedef unsigned char UINT8;
typedef UINT8 tSmallUInt;
typedef unsigned long long UINT64;
typedef UINT64 tKeccakLane;
#define cKeccakLaneSizeInBits (sizeof(tKeccakLane) * 8)
#define cKeccakNumberOfRounds 24
static tKeccakLane KeccakF_RoundConstants[cKeccakNumberOfRounds] PROGMEM =
{
(tKeccakLane)0x0000000000000001ULL,
(tKeccakLane)0x0000000000008082ULL,
(tKeccakLane)0x800000000000808aULL,
(tKeccakLane)0x8000000080008000ULL,
(tKeccakLane)0x000000000000808bULL,
(tKeccakLane)0x0000000080000001ULL,
(tKeccakLane)0x8000000080008081ULL,
(tKeccakLane)0x8000000000008009ULL,
(tKeccakLane)0x000000000000008aULL,
(tKeccakLane)0x0000000000000088ULL,
(tKeccakLane)0x0000000080008009ULL,
(tKeccakLane)0x000000008000000aULL,
(tKeccakLane)0x000000008000808bULL,
(tKeccakLane)0x800000000000008bULL,
(tKeccakLane)0x8000000000008089ULL,
(tKeccakLane)0x8000000000008003ULL,
(tKeccakLane)0x8000000000008002ULL,
(tKeccakLane)0x8000000000000080ULL,
(tKeccakLane)0x000000000000800aULL,
(tKeccakLane)0x800000008000000aULL,
(tKeccakLane)0x8000000080008081ULL,
(tKeccakLane)0x8000000000008080ULL,
(tKeccakLane)0x0000000080000001ULL,
(tKeccakLane)0x8000000080008008ULL
};
static tSmallUInt KeccakF_RotationConstants[24] PROGMEM =
{
ROT_CODE( 1), ROT_CODE( 3), ROT_CODE( 6), ROT_CODE(10), ROT_CODE(15),
ROT_CODE(21), ROT_CODE(28), ROT_CODE(36), ROT_CODE(45), ROT_CODE(55),
ROT_CODE( 2), ROT_CODE(14), ROT_CODE(27), ROT_CODE(41), ROT_CODE(56),
ROT_CODE( 8), ROT_CODE(25), ROT_CODE(43), ROT_CODE(62), ROT_CODE(18),
ROT_CODE(39), ROT_CODE(61), ROT_CODE(20), ROT_CODE(44)
};
static tSmallUInt KeccakF_PiLane[24] PROGMEM =
{
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
};
static tSmallUInt KeccakF_Mod5[10] PROGMEM =
{
0, 1, 2, 3, 4, 0, 1, 2, 3, 4
};
void KeccakF( tKeccakLane * state )
{
tSmallUInt round;
tKeccakLane C[5];
// prepare Theta
{
tSmallUInt x;
tKeccakLane * pC;
for ( x = 0, pC = C; x < 5; ++x, ++pC )
{
*pC = state[x] ^ state[5 + x] ^ state[10 + x] ^ state[15 + x] ^ state[20 + x];
}
}
for( round = 0; round < cKeccakNumberOfRounds; ++round )
{
// Theta
{
tSmallUInt x;
for ( x = 0; x < 5; ++x )
{
tKeccakLane temp;
tSmallUInt y;
temp = rotate64_1bit_left( C[pgm_read_byte((KeccakF_Mod5+1)+x)] );
temp ^= C[pgm_read_byte((KeccakF_Mod5+4)+x)];
for ( y = 0; y < 25; y += 5 )
{
state[y + x] ^= temp;
}
}
}
// Rho Pi
{
tKeccakLane temp;
tSmallUInt x;
temp = state[1];
for ( x = 0; x < 24; ++x )
{
tSmallUInt t;
tKeccakLane T[1];
t = pgm_read_byte(&KeccakF_PiLane[x]);
T[0] = state[t];
state[t] = rotate64left_code( temp, pgm_read_byte(&KeccakF_RotationConstants[x]) );
temp = T[0];
}
}
// Chi Iota Prepare Theta
{
tSmallUInt z;
UINT8 * p = (unsigned char *)state;
UINT8 * pC = (unsigned char *)C;
for( z = 0; z < 8; ++z, ++p, ++pC )
{
tSmallUInt y;
UINT8 c0, c1, c2, c3, c4, t;
c0 = c1 = c2 = c3 = c4 = 0;
for( y = 5; y != 0; --y, p += 40 )
{
UINT8 a0 = *p;
UINT8 a1 = *(p+8);
UINT8 a2 = *(p+16);
UINT8 a3 = *(p+24);
UINT8 a4 = *(p+32);
*p = t = a0 ^ ((~a1) & a2); c0 ^= t;
*(p+8) = t = a1 ^ ((~a2) & a3); c1 ^= t;
*(p+16) = a2 ^= ((~a3) & a4); c2 ^= a2;
*(p+24) = a3 ^= ((~a4) & a0); c3 ^= a3;
*(p+32) = a4 ^= ((~a0) & a1); c4 ^= a4;
}
p -= 5 * 5 * 8;
y = pgm_read_byte( (UINT8 *)(KeccakF_RoundConstants+round) + z );
*p ^= y;
*pC = c0 ^ y;
*(pC+ 8) = c1;
*(pC+16) = c2;
*(pC+24) = c3;
*(pC+32) = c4;
}
}
}
}

View File

@ -1,647 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer, hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "Keccak-avr8-settings.h"
#include "crypto_hash.h"
#define cKeccakR_SizeInBytes (cKeccakR/8)
#ifndef crypto_hash_BYTES
#ifdef cKeccakFixedOutputLengthInBytes
#define crypto_hash_BYTES cKeccakFixedOutputLengthInBytes
#else
#define crypto_hash_BYTES cKeccakR_SizeInBytes
#endif
#endif
// Registers used in all routines
#define zero 1
#define rpState 24
#define rX 26
#define rY 28
#define rZ 30
/*
* int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
*
* argument out is passed in r24:r25
* argument in is passed in r22:r23
* argument inlen is passed in r14:r21, only lowest 16-bits (r14-r15) are used
*/
.global crypto_hash // populate.py, please update crypto_hash
crypto_hash: // populate.py, please update crypto_hash
// crypto_hash only registers
#define rT1 16
#define rT2 17
#define rT3 18
#define rInLen 22 //(2 regs)
#define sp 0x3D
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
push r28
push r29
// Allocate state (25*8) + C variables (5*8)
in rZ, sp
in rZ+1, sp+1
subi rZ, 240
sbci rZ+1, 0
in r0, 0x3F
cli
out sp+1, rZ+1
out sp, rZ
out 0x3F, r0
adiw rZ, 41 // pointer to start of state, end of C, compensate post decrement
push r24 // save out pointer
push r25
movw rpState, rZ
movw rY, r22 //y contains in pointer
movw rInLen, r14
ldi rT3, 5*5*8 //clear state
clearStateLoop:
st z+, zero
dec rT3
brne clearStateLoop
// Full blocks
cpi rInLen, cKeccakR_SizeInBytes
cpc rInLen+1, zero
brcs ch_lastblock
ch_FullRateLoop:
ldi rT3, cKeccakR_SizeInBytes
movw rZ, rpState
ch_XorLanesLoop:
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
subi rT3, 1
brne ch_XorLanesLoop
push rY
push rY+1
call KeccakF
pop rY+1
pop rY
subi rInLen, cKeccakR_SizeInBytes
sbci rInLen+1, 0
cpi rInLen, cKeccakR_SizeInBytes
cpc rInLen+1, zero
brcc ch_FullRateLoop
ch_lastblock: // XOR last uncomplete block into state
movw rZ, rpState
subi rInLen, 0
breq ch_Padding
ch_xorBytesLoop:
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
subi rInLen, 1
brne ch_xorBytesLoop
ch_Padding:
ldi rT1, 1
ld rT2, Z
eor rT1, rT2
st Z, rT1
ldi rZ, cKeccakR_SizeInBytes-1
add rZ, rpState
mov rZ+1, rpState+1
adc rZ+1, zero
ld rT1, Z
subi rT1, 0x80
st Z, rT1
call KeccakF
//output
ldi rT3, crypto_hash_BYTES
movw rY, rpState
pop rZ+1 ; restore out pointer
pop rZ
outputLoop:
ld rT1, Y+
st Z+, rT1
dec rT3
brne outputLoop
// Free state and pop registers
ldi rZ, 199
add rpState, rZ
adc rpState+1, zero
in r0, 0x3F
cli
out sp+1, rpState+1
out sp, rpState
out 0x3F, r0
pop r29
pop r28
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
// return 0
mov r24, zero
mov r25, zero
#undef rInLen
#undef rT1
#undef rT2
#undef rT3
#undef sp
ret
//#define ROT_BIT(a) (a <= 4) ? ((a == 0) ? 0x80 : (a & 7)) : (0x80 | (8-a))
#define ROT_BIT(a) ((a) & 7)
#define ROT_BYTE(a) (((a)/8 + !!(((a)%8) > 4)) & 7)
KeccakF_RhoPiConstants:
.BYTE ROT_BIT( 1), ROT_BYTE( 3), 10 * 8
.BYTE ROT_BIT( 3), ROT_BYTE( 6), 7 * 8
.BYTE ROT_BIT( 6), ROT_BYTE(10), 11 * 8
.BYTE ROT_BIT(10), ROT_BYTE(15), 17 * 8
.BYTE ROT_BIT(15), ROT_BYTE(21), 18 * 8
.BYTE ROT_BIT(21), ROT_BYTE(28), 3 * 8
.BYTE ROT_BIT(28), ROT_BYTE(36), 5 * 8
.BYTE ROT_BIT(36), ROT_BYTE(45), 16 * 8
.BYTE ROT_BIT(45), ROT_BYTE(55), 8 * 8
.BYTE ROT_BIT(55), ROT_BYTE( 2), 21 * 8
.BYTE ROT_BIT( 2), ROT_BYTE(14), 24 * 8
.BYTE ROT_BIT(14), ROT_BYTE(27), 4 * 8
.BYTE ROT_BIT(27), ROT_BYTE(41), 15 * 8
.BYTE ROT_BIT(41), ROT_BYTE(56), 23 * 8
.BYTE ROT_BIT(56), ROT_BYTE( 8), 19 * 8
.BYTE ROT_BIT( 8), ROT_BYTE(25), 13 * 8
.BYTE ROT_BIT(25), ROT_BYTE(43), 12 * 8
.BYTE ROT_BIT(43), ROT_BYTE(62), 2 * 8
.BYTE ROT_BIT(62), ROT_BYTE(18), 20 * 8
.BYTE ROT_BIT(18), ROT_BYTE(39), 14 * 8
.BYTE ROT_BIT(39), ROT_BYTE(61), 22 * 8
.BYTE ROT_BIT(61), ROT_BYTE(20), 9 * 8
.BYTE ROT_BIT(20), ROT_BYTE(44), 6 * 8
.BYTE ROT_BIT(44), ROT_BYTE( 1), 1 * 8
KeccakF_RoundConstants:
.BYTE 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x8a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x8b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x81, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x09, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x8b, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x81, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x08, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0xFF, 0 //terminator
.text
// KeccakF
// Not callable from C!
//
// argument rpState is passed in r24:r25
//
KeccakF:
// Variables used in multiple operations
#define rTemp 2 // 8 regs (2-9)
#define rTempBis 10 // 8 regs (10-17)
#define rTempTer 18 // 2 regs (18-19)
#define pRound 20 // 2 regs (20-21)
// Initial Prepare Theta
#define TCIPx rTempTer
movw rZ, rpState // Z points to 5 C lanes
sbiw rZ, 40
movw rY, rpState
ldi TCIPx, 5*8
KeccakInitialPrepTheta_Loop:
ld r0, Y
adiw rY, 40
ld rTemp, Y
adiw rY, 40
eor r0, rTemp
ld rTemp, Y
adiw rY, 40
eor r0, rTemp
ld rTemp, Y
eor r0, rTemp
ldd rTemp, Y+40
eor r0, rTemp
st Z+, r0
subi rY, 119
sbc rY+1, zero
dec TCIPx
brne KeccakInitialPrepTheta_Loop
#undef TCIPx
ldi pRound, lo8(KeccakF_RoundConstants)
ldi pRound+1, hi8(KeccakF_RoundConstants)
Keccak_RoundLoop:
// Theta
#define TCplus rX
#define TCminus rZ
#define TCcoordX rTempTer
#define TCcoordY rTempTer+1
movw TCminus, rpState
sbiw TCminus, 1*8
movw TCplus, rpState
sbiw TCplus, 4*8
movw rY, rpState
ldi TCcoordX, 0x16
KeccakTheta_Loop1:
ld rTemp+0, X+
ld rTemp+1, X+
ld rTemp+2, X+
ld rTemp+3, X+
ld rTemp+4, X+
ld rTemp+5, X+
ld rTemp+6, X+
ld rTemp+7, X+
lsl rTemp+0
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp+0, zero
ld r0, Z+
eor rTemp+0, r0
ld r0, Z+
eor rTemp+1, r0
ld r0, Z+
eor rTemp+2, r0
ld r0, Z+
eor rTemp+3, r0
ld r0, Z+
eor rTemp+4, r0
ld r0, Z+
eor rTemp+5, r0
ld r0, Z+
eor rTemp+6, r0
ld r0, Z+
eor rTemp+7, r0
ldi TCcoordY, 5
KeccakTheta_Loop2:
ld r0, Y
eor r0, rTemp+0
st Y+, r0
ld r0, Y
eor r0, rTemp+1
st Y+, r0
ld r0, Y
eor r0, rTemp+2
st Y+, r0
ld r0, Y
eor r0, rTemp+3
st Y+, r0
ld r0, Y
eor r0, rTemp+4
st Y+, r0
ld r0, Y
eor r0, rTemp+5
st Y+, r0
ld r0, Y
eor r0, rTemp+6
st Y+, r0
ld r0, Y
eor r0, rTemp+7
st Y+, r0
adiw rY, 32
dec TCcoordY
brne KeccakTheta_Loop2
subi rY, 200-8
sbc rY+1, zero
lsr TCcoordX
brcc 1f
breq KeccakTheta_End
rjmp KeccakTheta_Loop1
1:
cpi TCcoordX, 0x0B
brne 2f
sbiw TCminus, 40
rjmp KeccakTheta_Loop1
2:
sbiw TCplus, 40
rjmp KeccakTheta_Loop1
KeccakTheta_End:
#undef TCplus
#undef TCminus
#undef TCcoordX
#undef TCcoordY
// Rho Pi
#define RPindex rTempTer+0
#define RPTemp rTempTer+1
sbiw rY, 32
ld rTemp+0, Y+
ld rTemp+1, Y+
ld rTemp+2, Y+
ld rTemp+3, Y+
ld rTemp+4, Y+
ld rTemp+5, Y+
ld rTemp+6, Y+
ld rTemp+7, Y+
ldi rZ, lo8(KeccakF_RhoPiConstants)
ldi rZ+1, hi8(KeccakF_RhoPiConstants)
KeccakRhoPi_Loop:
; do bit rotation
lpm RPTemp, Z+ ;get nuber of bits to rotate
cpi RPTemp, 5
brcs rotate64_nbit_leftOrNot
neg RPTemp
andi RPTemp, 3
rotate64_nbit_right:
bst rTemp, 0
ror rTemp+7
ror rTemp+6
ror rTemp+5
ror rTemp+4
ror rTemp+3
ror rTemp+2
ror rTemp+1
ror rTemp
bld rTemp+7, 7
dec RPTemp
brne rotate64_nbit_right
rjmp KeccakRhoPi_RhoBitRotateDone
rotate64_nbit_leftOrNot:
tst RPTemp
breq KeccakRhoPi_RhoBitRotateDone
rotate64_nbit_left:
lsl rTemp
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp, r1
dec RPTemp
brne rotate64_nbit_left
KeccakRhoPi_RhoBitRotateDone:
lpm r0, Z+ ;get number of bytes to rotate
lpm RPindex, Z+ ;get index in state
movw rY, rpState
add rY, RPindex
adc rY+1, zero
ldi rX, rTempBis
add rX, r0
mov rX+1, zero
ldi RPTemp, 8
KeccakRhoPi_PiByteRotLoop:
ld r0, Y+
st X+, r0
cpi rX, rTempBis+8
brne KeccakRhoPi_PiByteRotFirst
ldi rX, rTempBis
KeccakRhoPi_PiByteRotFirst:
dec RPTemp
brne KeccakRhoPi_PiByteRotLoop
sbiw rY, 8
st Y+, rTemp+0
st Y+, rTemp+1
st Y+, rTemp+2
st Y+, rTemp+3
st Y+, rTemp+4
st Y+, rTemp+5
st Y+, rTemp+6
st Y+, rTemp+7
movw rTemp+0, rTempBis+0
movw rTemp+2, rTempBis+2
movw rTemp+4, rTempBis+4
movw rTemp+6, rTempBis+6
KeccakRhoPi_RhoDone:
subi RPindex, 8
brne KeccakRhoPi_Loop
#undef RPindex
#undef RPTemp
// Chi Iota prepare Theta
#define CIPTa0 rTemp
#define CIPTa1 rTemp+1
#define CIPTa2 rTemp+2
#define CIPTa3 rTemp+3
#define CIPTa4 rTemp+4
#define CIPTc0 rTempBis
#define CIPTc1 rTempBis+1
#define CIPTc2 rTempBis+2
#define CIPTc3 rTempBis+3
#define CIPTc4 rTempBis+4
#define CIPTz rTempBis+6
#define CIPTy rTempBis+7
movw rY, rpState
movw rX, rpState ; 5 * C
sbiw rX, 40
movw rZ, pRound
ldi CIPTz, 8
KeccakChiIotaPrepareTheta_zLoop:
mov CIPTc0, zero
mov CIPTc1, zero
movw CIPTc2, CIPTc0
mov CIPTc4, zero
ldi CIPTy, 5
KeccakChiIotaPrepareTheta_yLoop:
ld CIPTa0, Y
ldd CIPTa1, Y+8
ldd CIPTa2, Y+16
ldd CIPTa3, Y+24
ldd CIPTa4, Y+32
;*p = t = a0 ^ ((~a1) & a2); c0 ^= t;
mov r0, CIPTa1
com r0
and r0, CIPTa2
eor r0, CIPTa0
eor CIPTc0, r0
st Y, r0
;*(p+8) = t = a1 ^ ((~a2) & a3); c1 ^= t;
mov r0, CIPTa2
com r0
and r0, CIPTa3
eor r0, CIPTa1
eor CIPTc1, r0
std Y+8, r0
;*(p+16) = a2 ^= ((~a3) & a4); c2 ^= a2;
mov r0, CIPTa3
com r0
and r0, CIPTa4
eor r0, CIPTa2
eor CIPTc2, r0
std Y+16, r0
;*(p+24) = a3 ^= ((~a4) & a0); c3 ^= a3;
mov r0, CIPTa4
com r0
and r0, CIPTa0
eor r0, CIPTa3
eor CIPTc3, r0
std Y+24, r0
;*(p+32) = a4 ^= ((~a0) & a1); c4 ^= a4;
com CIPTa0
and CIPTa0, CIPTa1
eor CIPTa0, CIPTa4
eor CIPTc4, CIPTa0
std Y+32, CIPTa0
adiw rY, 40
dec CIPTy
brne KeccakChiIotaPrepareTheta_yLoop
subi rY, 200
sbc rY+1, zero
lpm r0, Z+ ;Round Constant
ld CIPTa0, Y
eor CIPTa0, r0
st Y+, CIPTa0
movw pRound, rZ
movw rZ, rX
eor CIPTc0, r0
st Z+, CIPTc0
std Z+7, CIPTc1
std Z+15, CIPTc2
std Z+23, CIPTc3
std Z+31, CIPTc4
movw rX, rZ
movw rZ, pRound
dec CIPTz
brne KeccakChiIotaPrepareTheta_zLoop
#undef CIPTa0
#undef CIPTa1
#undef CIPTa2
#undef CIPTa3
#undef CIPTa4
#undef CIPTc0
#undef CIPTc1
#undef CIPTc2
#undef CIPTc3
#undef CIPTc4
#undef CIPTz
#undef CIPTy
;Check for terminator
lpm r0, Z
inc r0
breq Keccak_Done
rjmp Keccak_RoundLoop
Keccak_Done:
ret
#undef rTemp
#undef rTempBis
#undef rTempTer
#undef pRound
#undef rpState
#undef zero
#undef rX
#undef rY
#undef rZ

View File

@ -1,934 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer, hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include "Keccak-avr8-settings.h"
#include "crypto_hash.h"
#define cKeccakR_SizeInBytes (cKeccakR/8)
#ifndef crypto_hash_BYTES
#ifdef cKeccakFixedOutputLengthInBytes
#define crypto_hash_BYTES cKeccakFixedOutputLengthInBytes
#else
#define crypto_hash_BYTES cKeccakR_SizeInBytes
#endif
#endif
// Registers used in all routines
#define zero 1
#define rpState 24
#define rX 26
#define rY 28
#define rZ 30
/*
* int crypto_hash( unsigned char *out, const unsigned char *in, unsigned long long inlen )
*
* argument out is passed in r24:r25
* argument in is passed in r22:r23
* argument inlen is passed in r14:r21, only lowest 16-bits (r14-r15) are used
*/
.global crypto_hash // populate.py, please update crypto_hash
crypto_hash: // populate.py, please update crypto_hash
// crypto_hash only registers
#define rInLen 16 //(2 regs)
#define rT1 18
#define rT2 19
#define rT3 20
#define sp 0x3D
push r2
push r3
push r4
push r5
push r6
push r7
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
push r28
push r29
// Allocate state (25*8) + C variables (5*8)
in rZ, sp
in rZ+1, sp+1
subi rZ, 240
sbci rZ+1, 0
in r0, 0x3F
cli
out sp+1, rZ+1
out sp, rZ
out 0x3F, r0
adiw rZ, 41 // pointer to start of state, end of C, compensate post decrement
push r24 // save out pointer
push r25
movw rpState, rZ
movw rY, r22 //y contains in pointer
movw rInLen, r14
ldi rT3, 5*5*2 //clear state (4 bytes each iteration)
clearStateLoop:
st z+, zero
st z+, zero
st z+, zero
st z+, zero
dec rT3
brne clearStateLoop
// Full blocks
cpi rInLen, cKeccakR_SizeInBytes
cpc rInLen+1, zero
brcs ch_lastblock
ch_FullRateLoop:
ldi rT3, cKeccakR_SizeInBytes/8
movw rZ, rpState
ch_XorLanesLoop:
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
subi rT3, 1
brne ch_XorLanesLoop
push rY
push rY+1
push rInLen
push rInLen+1
call KeccakF
pop rInLen+1
pop rInLen
pop rY+1
pop rY
subi rInLen, cKeccakR_SizeInBytes
sbci rInLen+1, 0
cpi rInLen, cKeccakR_SizeInBytes
cpc rInLen+1, zero
brcc ch_FullRateLoop
ch_lastblock: // XOR last uncomplete block into state
movw rZ, rpState
lsr rInLen
brcc ch_xorBytes2
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
subi rInLen, 0
ch_xorBytes2:
breq ch_Padding
ch_xorBytes2Loop:
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
ld rT1, Y+
ld rT2, Z
eor rT1, rT2
st Z+, rT1
subi rInLen, 1
brne ch_xorBytes2Loop
ch_Padding:
ldi rT1, 1
ld rT2, Z
eor rT1, rT2
st Z, rT1
ldi rZ, cKeccakR_SizeInBytes-1
add rZ, rpState
mov rZ+1, rpState+1
adc rZ+1, zero
ld rT1, Z
subi rT1, 0x80
st Z, rT1
call KeccakF
//output
ldi rT3, crypto_hash_BYTES/4 ; copy 4 bytes per iteration
movw rY, rpState
pop rZ+1 ; restore out pointer
pop rZ
outputLoop:
ld rT1, Y+
st Z+, rT1
ld rT1, Y+
st Z+, rT1
ld rT1, Y+
st Z+, rT1
ld rT1, Y+
st Z+, rT1
dec rT3
brne outputLoop
// Free state and pop registers
ldi rZ, 199
add rpState, rZ
adc rpState+1, zero
in r0, 0x3F
cli
out sp+1, rpState+1
out sp, rpState
out 0x3F, r0
pop r29
pop r28
pop r17
pop r16
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop r7
pop r6
pop r5
pop r4
pop r3
pop r2
// return 0
mov r24, zero
mov r25, zero
#undef rInLen
#undef rT1
#undef rT2
#undef rT3
#undef sp
ret
#define ROT_BIT(a) ((a) & 7)
#define ROT_BYTE(a) ((((a)/8 + !!(((a)%8) > 4)) & 7) * 9)
KeccakF_RhoPiConstants:
.BYTE ROT_BIT( 1), ROT_BYTE( 3), 10 * 8
.BYTE ROT_BIT( 3), ROT_BYTE( 6), 7 * 8
.BYTE ROT_BIT( 6), ROT_BYTE(10), 11 * 8
.BYTE ROT_BIT(10), ROT_BYTE(15), 17 * 8
.BYTE ROT_BIT(15), ROT_BYTE(21), 18 * 8
.BYTE ROT_BIT(21), ROT_BYTE(28), 3 * 8
.BYTE ROT_BIT(28), ROT_BYTE(36), 5 * 8
.BYTE ROT_BIT(36), ROT_BYTE(45), 16 * 8
.BYTE ROT_BIT(45), ROT_BYTE(55), 8 * 8
.BYTE ROT_BIT(55), ROT_BYTE( 2), 21 * 8
.BYTE ROT_BIT( 2), ROT_BYTE(14), 24 * 8
.BYTE ROT_BIT(14), ROT_BYTE(27), 4 * 8
.BYTE ROT_BIT(27), ROT_BYTE(41), 15 * 8
.BYTE ROT_BIT(41), ROT_BYTE(56), 23 * 8
.BYTE ROT_BIT(56), ROT_BYTE( 8), 19 * 8
.BYTE ROT_BIT( 8), ROT_BYTE(25), 13 * 8
.BYTE ROT_BIT(25), ROT_BYTE(43), 12 * 8
.BYTE ROT_BIT(43), ROT_BYTE(62), 2 * 8
.BYTE ROT_BIT(62), ROT_BYTE(18), 20 * 8
.BYTE ROT_BIT(18), ROT_BYTE(39), 14 * 8
.BYTE ROT_BIT(39), ROT_BYTE(61), 22 * 8
.BYTE ROT_BIT(61), ROT_BYTE(20), 9 * 8
.BYTE ROT_BIT(20), ROT_BYTE(44), 6 * 8
.BYTE ROT_BIT(44), ROT_BYTE( 1), 1 * 8
KeccakF_RoundConstants:
.BYTE 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x82, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x8a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x8b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x81, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x09, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x09, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x8b, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x89, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x0a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
.BYTE 0x0a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x81, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80
.BYTE 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
.BYTE 0x08, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
.BYTE 0xFF, 0 //terminator
.text
// KeccakF
// Not callable from C!
//
// argument rpState is passed in r24:r25
//
KeccakF:
// Variables used in multiple operations
#define rTemp 2 // 8 regs (2-9)
#define rTempBis 10 // 8 regs (10-17)
#define rTempTer 18 // 4 regs (18-21)
#define pRound 22 // 2 regs (22-23)
// Initial Prepare Theta
#define TCIPx rTempTer
movw rZ, rpState // Z points to 8 C
sbiw rZ, 40
ldi TCIPx, 5
movw rY, rpState
KeccakInitialPrepTheta_Loop:
ld rTemp+0, Y+ ;state[x]
ld rTemp+1, Y+
ld rTemp+2, Y+
ld rTemp+3, Y+
ld rTemp+4, Y+
ld rTemp+5, Y+
ld rTemp+6, Y+
ld rTemp+7, Y+
adiw rY, 32
ld r0, Y+ ;state[5+x]
eor rTemp+0, r0
ld r0, Y+
eor rTemp+1, r0
ld r0, Y+
eor rTemp+2, r0
ld r0, Y+
eor rTemp+3, r0
ld r0, Y+
eor rTemp+4, r0
ld r0, Y+
eor rTemp+5, r0
ld r0, Y+
eor rTemp+6, r0
ld r0, Y+
eor rTemp+7, r0
adiw rY, 32
ld r0, Y+ ;state[10+x]
eor rTemp+0, r0
ld r0, Y+
eor rTemp+1, r0
ld r0, Y+
eor rTemp+2, r0
ld r0, Y+
eor rTemp+3, r0
ld r0, Y+
eor rTemp+4, r0
ld r0, Y+
eor rTemp+5, r0
ld r0, Y+
eor rTemp+6, r0
ld r0, Y+
eor rTemp+7, r0
adiw rY, 32
ld r0, Y+ ;state[15+x]
eor rTemp+0, r0
ld r0, Y+
eor rTemp+1, r0
ld r0, Y+
eor rTemp+2, r0
ld r0, Y+
eor rTemp+3, r0
ld r0, Y+
eor rTemp+4, r0
ld r0, Y+
eor rTemp+5, r0
ld r0, Y+
eor rTemp+6, r0
ld r0, Y+
eor rTemp+7, r0
adiw rY, 32
ld r0, Y+ ;state[20+x]
eor rTemp+0, r0
ld r0, Y+
eor rTemp+1, r0
ld r0, Y+
eor rTemp+2, r0
ld r0, Y+
eor rTemp+3, r0
ld r0, Y+
eor rTemp+4, r0
ld r0, Y+
eor rTemp+5, r0
ld r0, Y+
eor rTemp+6, r0
ld r0, Y+
eor rTemp+7, r0
st Z+, rTemp+0
st Z+, rTemp+1
st Z+, rTemp+2
st Z+, rTemp+3
st Z+, rTemp+4
st Z+, rTemp+5
st Z+, rTemp+6
st Z+, rTemp+7
subi rY, 160
sbc rY+1, zero
subi TCIPx, 1
breq KeccakInitialPrepTheta_Done
rjmp KeccakInitialPrepTheta_Loop
KeccakInitialPrepTheta_Done:
#undef TCIPx
ldi pRound, lo8(KeccakF_RoundConstants)
ldi pRound+1, hi8(KeccakF_RoundConstants)
Keccak_RoundLoop:
// Theta
#define TCplus rX
#define TCminus rZ
#define TCcoordX rTempTer
#define TCcoordY rTempTer+1
movw TCminus, rpState
sbiw TCminus, 1*8
movw TCplus, rpState
sbiw TCplus, 4*8
movw rY, rpState
ldi TCcoordX, 0x16
KeccakTheta_Loop1:
ld rTemp+0, X+
ld rTemp+1, X+
ld rTemp+2, X+
ld rTemp+3, X+
ld rTemp+4, X+
ld rTemp+5, X+
ld rTemp+6, X+
ld rTemp+7, X+
lsl rTemp+0
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp+0, zero
ld r0, Z+
eor rTemp+0, r0
ld r0, Z+
eor rTemp+1, r0
ld r0, Z+
eor rTemp+2, r0
ld r0, Z+
eor rTemp+3, r0
ld r0, Z+
eor rTemp+4, r0
ld r0, Z+
eor rTemp+5, r0
ld r0, Z+
eor rTemp+6, r0
ld r0, Z+
eor rTemp+7, r0
ldi TCcoordY, 5
KeccakTheta_Loop2:
ld r0, Y
eor r0, rTemp+0
st Y+, r0
ld r0, Y
eor r0, rTemp+1
st Y+, r0
ld r0, Y
eor r0, rTemp+2
st Y+, r0
ld r0, Y
eor r0, rTemp+3
st Y+, r0
ld r0, Y
eor r0, rTemp+4
st Y+, r0
ld r0, Y
eor r0, rTemp+5
st Y+, r0
ld r0, Y
eor r0, rTemp+6
st Y+, r0
ld r0, Y
eor r0, rTemp+7
st Y+, r0
adiw rY, 32
dec TCcoordY
brne KeccakTheta_Loop2
subi rY, 200-8
sbc rY+1, zero
lsr TCcoordX
brcc 1f
breq KeccakTheta_End
rjmp KeccakTheta_Loop1
1:
cpi TCcoordX, 0x0B
brne 2f
sbiw TCminus, 40
rjmp KeccakTheta_Loop1
2:
sbiw TCplus, 40
rjmp KeccakTheta_Loop1
KeccakTheta_End:
#undef TCplus
#undef TCminus
#undef TCcoordX
#undef TCcoordY
// Rho Pi
#define RPpConst rTempTer // 2 regs
#define RPindex rTempTer+2
#define RPpBitRot rX
#define RPpByteRot pRound
sbiw rY, 32
ld rTemp+0, Y+
ld rTemp+1, Y+
ld rTemp+2, Y+
ld rTemp+3, Y+
ld rTemp+4, Y+
ld rTemp+5, Y+
ld rTemp+6, Y+
ld rTemp+7, Y+
push pRound
push pRound+1
ldi RPpConst, lo8(KeccakF_RhoPiConstants)
ldi RPpConst+1, hi8(KeccakF_RhoPiConstants)
ldi RPpBitRot, pm_lo8(bit_rot_jmp_table)
ldi RPpBitRot+1, pm_hi8(bit_rot_jmp_table)
ldi RPpByteRot, pm_lo8(rotate64_0byte_left)
ldi RPpByteRot+1, pm_hi8(rotate64_0byte_left)
KeccakRhoPi_Loop:
; get rotation codes and state index
movw rZ, RPpConst
lpm r0, Z+ ;bits
lpm rTempBis, Z+ ;bytes
lpm RPindex, Z+
movw RPpConst, rZ
; do bit rotation
movw rZ, RPpBitRot
add rZ, r0
adc rZ+1, zero
ijmp
KeccakRhoPi_RhoBitRotateDone:
movw rY, rpState
add rY, RPindex
adc rY+1, zero
movw rZ, RPpByteRot
add rZ, rTempBis
adc rZ+1, zero
ijmp
KeccakRhoPi_PiStore:
sbiw rY, 8
st Y+, rTemp+0
st Y+, rTemp+1
st Y+, rTemp+2
st Y+, rTemp+3
st Y+, rTemp+4
st Y+, rTemp+5
st Y+, rTemp+6
st Y+, rTemp+7
movw rTemp+0, rTempBis+0
movw rTemp+2, rTempBis+2
movw rTemp+4, rTempBis+4
movw rTemp+6, rTempBis+6
KeccakRhoPi_RhoDone:
subi RPindex, 8
brne KeccakRhoPi_Loop
pop pRound+1
pop pRound
#undef RPpConst
#undef RPindex
#undef RPpBitRot
#undef RPpByteRot
// Chi Iota prepare Theta
#define CIPTa0 rTemp
#define CIPTa1 rTemp+1
#define CIPTa2 rTemp+2
#define CIPTa3 rTemp+3
#define CIPTa4 rTemp+4
#define CIPTc0 rTempBis
#define CIPTc1 rTempBis+1
#define CIPTc2 rTempBis+2
#define CIPTc3 rTempBis+3
#define CIPTc4 rTempBis+4
#define CIPTz rTempBis+6
#define CIPTy rTempBis+7
movw rY, rpState
movw rX, rpState ; 5 * C
sbiw rX, 40
movw rZ, pRound
ldi CIPTz, 8
KeccakChiIotaPrepareTheta_zLoop:
mov CIPTc0, zero
mov CIPTc1, zero
movw CIPTc2, CIPTc0
mov CIPTc4, zero
ldi CIPTy, 5
KeccakChiIotaPrepareTheta_yLoop:
ld CIPTa0, Y
ldd CIPTa1, Y+8
ldd CIPTa2, Y+16
ldd CIPTa3, Y+24
ldd CIPTa4, Y+32
;*p = t = a0 ^ ((~a1) & a2); c0 ^= t;
mov r0, CIPTa1
com r0
and r0, CIPTa2
eor r0, CIPTa0
eor CIPTc0, r0
st Y, r0
;*(p+8) = t = a1 ^ ((~a2) & a3); c1 ^= t;
mov r0, CIPTa2
com r0
and r0, CIPTa3
eor r0, CIPTa1
eor CIPTc1, r0
std Y+8, r0
;*(p+16) = a2 ^= ((~a3) & a4); c2 ^= a2;
mov r0, CIPTa3
com r0
and r0, CIPTa4
eor r0, CIPTa2
eor CIPTc2, r0
std Y+16, r0
;*(p+24) = a3 ^= ((~a4) & a0); c3 ^= a3;
mov r0, CIPTa4
com r0
and r0, CIPTa0
eor r0, CIPTa3
eor CIPTc3, r0
std Y+24, r0
;*(p+32) = a4 ^= ((~a0) & a1); c4 ^= a4;
com CIPTa0
and CIPTa0, CIPTa1
eor CIPTa0, CIPTa4
eor CIPTc4, CIPTa0
std Y+32, CIPTa0
adiw rY, 40
dec CIPTy
brne KeccakChiIotaPrepareTheta_yLoop
subi rY, 200
sbc rY+1, zero
lpm r0, Z+ ;Round Constant
ld CIPTa0, Y
eor CIPTa0, r0
st Y+, CIPTa0
movw pRound, rZ
movw rZ, rX
eor CIPTc0, r0
st Z+, CIPTc0
std Z+7, CIPTc1
std Z+15, CIPTc2
std Z+23, CIPTc3
std Z+31, CIPTc4
movw rX, rZ
movw rZ, pRound
dec CIPTz
brne KeccakChiIotaPrepareTheta_zLoop
#undef CIPTa0
#undef CIPTa1
#undef CIPTa2
#undef CIPTa3
#undef CIPTa4
#undef CIPTc0
#undef CIPTc1
#undef CIPTc2
#undef CIPTc3
#undef CIPTc4
#undef CIPTz
#undef CIPTy
;Check for terminator
lpm r0, Z
inc r0
breq Keccak_Done
rjmp Keccak_RoundLoop
Keccak_Done:
ret
bit_rot_jmp_table:
rjmp KeccakRhoPi_RhoBitRotateDone
rjmp rotate64_1bit_left
rjmp rotate64_2bit_left
rjmp rotate64_3bit_left
rjmp rotate64_4bit_left
rjmp rotate64_3bit_right
rjmp rotate64_2bit_right
rjmp rotate64_1bit_right
rotate64_4bit_left:
lsl rTemp
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp, r1
rotate64_3bit_left:
lsl rTemp
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp, r1
rotate64_2bit_left:
lsl rTemp
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp, r1
rotate64_1bit_left:
lsl rTemp
rol rTemp+1
rol rTemp+2
rol rTemp+3
rol rTemp+4
rol rTemp+5
rol rTemp+6
rol rTemp+7
adc rTemp, r1
rjmp KeccakRhoPi_RhoBitRotateDone
rotate64_3bit_right:
bst rTemp, 0
ror rTemp+7
ror rTemp+6
ror rTemp+5
ror rTemp+4
ror rTemp+3
ror rTemp+2
ror rTemp+1
ror rTemp
bld rTemp+7, 7
rotate64_2bit_right:
bst rTemp, 0
ror rTemp+7
ror rTemp+6
ror rTemp+5
ror rTemp+4
ror rTemp+3
ror rTemp+2
ror rTemp+1
ror rTemp
bld rTemp+7, 7
rotate64_1bit_right:
bst rTemp, 0
ror rTemp+7
ror rTemp+6
ror rTemp+5
ror rTemp+4
ror rTemp+3
ror rTemp+2
ror rTemp+1
ror rTemp
bld rTemp+7, 7
rjmp KeccakRhoPi_RhoBitRotateDone
/*
** Each byte rotate routine must be 9 instructions long.
*/
rotate64_0byte_left:
ld rTempBis+0, Y+
ld rTempBis+1, Y+
ld rTempBis+2, Y+
ld rTempBis+3, Y+
ld rTempBis+4, Y+
ld rTempBis+5, Y+
ld rTempBis+6, Y+
ld rTempBis+7, Y+
rjmp KeccakRhoPi_PiStore
rotate64_1byte_left:
ld rTempBis+1, Y+
ld rTempBis+2, Y+
ld rTempBis+3, Y+
ld rTempBis+4, Y+
ld rTempBis+5, Y+
ld rTempBis+6, Y+
ld rTempBis+7, Y+
ld rTempBis+0, Y+
rjmp KeccakRhoPi_PiStore
rotate64_2byte_left:
ld rTempBis+2, Y+
ld rTempBis+3, Y+
ld rTempBis+4, Y+
ld rTempBis+5, Y+
ld rTempBis+6, Y+
ld rTempBis+7, Y+
ld rTempBis+0, Y+
ld rTempBis+1, Y+
rjmp KeccakRhoPi_PiStore
rotate64_3byte_left:
ld rTempBis+3, Y+
ld rTempBis+4, Y+
ld rTempBis+5, Y+
ld rTempBis+6, Y+
ld rTempBis+7, Y+
ld rTempBis+0, Y+
ld rTempBis+1, Y+
ld rTempBis+2, Y+
rjmp KeccakRhoPi_PiStore
rotate64_4byte_left:
ld rTempBis+4, Y+
ld rTempBis+5, Y+
ld rTempBis+6, Y+
ld rTempBis+7, Y+
ld rTempBis+0, Y+
ld rTempBis+1, Y+
ld rTempBis+2, Y+
ld rTempBis+3, Y+
rjmp KeccakRhoPi_PiStore
rotate64_5byte_left:
ld rTempBis+5, Y+
ld rTempBis+6, Y+
ld rTempBis+7, Y+
ld rTempBis+0, Y+
ld rTempBis+1, Y+
ld rTempBis+2, Y+
ld rTempBis+3, Y+
ld rTempBis+4, Y+
rjmp KeccakRhoPi_PiStore
rotate64_6byte_left:
ld rTempBis+6, Y+
ld rTempBis+7, Y+
ld rTempBis+0, Y+
ld rTempBis+1, Y+
ld rTempBis+2, Y+
ld rTempBis+3, Y+
ld rTempBis+4, Y+
ld rTempBis+5, Y+
rjmp KeccakRhoPi_PiStore
rotate64_7byte_left:
ld rTempBis+7, Y+
ld rTempBis+0, Y+
ld rTempBis+1, Y+
ld rTempBis+2, Y+
ld rTempBis+3, Y+
ld rTempBis+4, Y+
ld rTempBis+5, Y+
ld rTempBis+6, Y+
rjmp KeccakRhoPi_PiStore
#undef rTemp
#undef rTempBis
#undef rTempTer
#undef pRound
#undef rpState
#undef zero
#undef rX
#undef rY
#undef rZ

View File

@ -1,446 +0,0 @@
@ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
@ Michaël Peeters and Gilles Van Assche. For more information, feedback or
@ questions, please refer to our website: http://keccak.noekeon.org/
@
@ Implementation by Ronny Van Keer, hereby denoted as "the implementer".
@
@ To the extent possible under law, the implementer has waived all copyright
@ and related or neighboring rights to the source code in this file.
@ http://creativecommons.org/publicdomain/zero/1.0/
@ This file was created from a .asm file
@ using the ads2gas.pl script.
.equ DO1STROUNDING, 0
@ PRESERVE8
.text
@// --- offsets in state
.equ Aba, 0*8
.equ Aga, 1*8
.equ Aka, 2*8
.equ Ama, 3*8
.equ Asa, 4*8
@// --- macros
.macro KeccakThetaRhoPiChiIota argA1, argA2, argA3, argA4, argA5
@Prepare Theta
@Ca = Aba^Aga^Aka^Ama^Asa@
@Ce = Abe^Age^Ake^Ame^Ase@
@Ci = Abi^Agi^Aki^Ami^Asi@
@Co = Abo^Ago^Ako^Amo^Aso@
@Cu = Abu^Agu^Aku^Amu^Asu@
@De = Ca^ROL64(Ci, 1)@
@Di = Ce^ROL64(Co, 1)@
@Do = Ci^ROL64(Cu, 1)@
@Du = Co^ROL64(Ca, 1)@
@Da = Cu^ROL64(Ce, 1)@
veor.64 q4, q6, q7
veor.64 q5, q9, q10
veor.64 d8, d8, d9
veor.64 d10, d10, d11
veor.64 d1, d8, d16
veor.64 d2, d10, d17
veor.64 q4, q11, q12
veor.64 q5, q14, q15
veor.64 d8, d8, d9
veor.64 d10, d10, d11
veor.64 d3, d8, d26
vadd.u64 q4, q1, q1
veor.64 d4, d10, d27
vmov.64 d0, d5
vsri.64 q4, q1, #63
vadd.u64 q5, q2, q2
veor.64 q4, q4, q0
vsri.64 q5, q2, #63
vadd.u64 d7, d1, d1
veor.64 \argA2, \argA2, d8
veor.64 q5, q5, q1
vsri.64 d7, d1, #63
vshl.u64 d1, \argA2, #44
veor.64 \argA3, \argA3, d9
veor.64 d7, d7, d4
@Ba = argA1^Da@
@Be = ROL64((argA2^De), 44)@
@Bi = ROL64((argA3^Di), 43)@
@Bo = ROL64((argA4^Do), 21)@
@Bu = ROL64((argA5^Du), 14)@
@argA2 = Be ^((~Bi)& Bo )@
@argA3 = Bi ^((~Bo)& Bu )@
@argA4 = Bo ^((~Bu)& Ba )@
@argA5 = Bu ^((~Ba)& Be )@
@argA1 = Ba ^((~Be)& Bi )@ argA1 ^= KeccakF1600RoundConstants[i+round]@
vsri.64 d1, \argA2, #64-44
vshl.u64 d2, \argA3, #43
vldr.64 d0, [sp, #\argA1]
veor.64 \argA4, \argA4, d10
vsri.64 d2, \argA3, #64-43
vshl.u64 d3, \argA4, #21
veor.64 \argA5, \argA5, d11
veor.64 d0, d0, d7
vsri.64 d3, \argA4, #64-21
vbic.64 d5, d2, d1
vshl.u64 d4, \argA5, #14
vbic.64 \argA2, d3, d2
vld1.64 d6, [r3]!
veor.64 d5, d0
vsri.64 d4, \argA5, #64-14
veor.64 d5, d6
vbic.64 \argA5, d1, d0
vbic.64 \argA3, d4, d3
vbic.64 \argA4, d0, d4
veor.64 \argA2, d1
vstr.64 d5, [sp, #\argA1]
veor.64 \argA3, d2
veor.64 \argA4, d3
veor.64 \argA5, d4
.endm
.macro KeccakThetaRhoPiChi1 argA1, argA2, argA3, argA4, argA5
@d2 = ROL64((argA1^Da), 3)@
@d3 = ROL64((argA2^De), 45)@
@d4 = ROL64((argA3^Di), 61)@
@d0 = ROL64((argA4^Do), 28)@
@d1 = ROL64((argA5^Du), 20)@
@argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
@argA2 = Be ^((~Bi)& Bo )@
@argA3 = Bi ^((~Bo)& Bu )@
@argA4 = Bo ^((~Bu)& Ba )@
@argA5 = Bu ^((~Ba)& Be )@
veor.64 \argA2, \argA2, d8
veor.64 \argA3, \argA3, d9
vshl.u64 d3, \argA2, #45
vldr.64 d6, [sp, #\argA1]
vshl.u64 d4, \argA3, #61
veor.64 \argA4, \argA4, d10
vsri.64 d3, \argA2, #64-45
veor.64 \argA5, \argA5, d11
vsri.64 d4, \argA3, #64-61
vshl.u64 d0, \argA4, #28
veor.64 d6, d6, d7
vshl.u64 d1, \argA5, #20
vbic.64 \argA3, d4, d3
vsri.64 d0, \argA4, #64-28
vbic.64 \argA4, d0, d4
vshl.u64 d2, d6, #3
vsri.64 d1, \argA5, #64-20
veor.64 \argA4, d3
vsri.64 d2, d6, #64-3
vbic.64 \argA5, d1, d0
vbic.64 d6, d2, d1
vbic.64 \argA2, d3, d2
veor.64 d6, d0
veor.64 \argA2, d1
vstr.64 d6, [sp, #\argA1]
veor.64 \argA3, d2
veor.64 d5, d6
veor.64 \argA5, d4
.endm
.macro KeccakThetaRhoPiChi2 argA1, argA2, argA3, argA4, argA5
@d4 = ROL64((argA1^Da), 18)@
@d0 = ROL64((argA2^De), 1)@
@d1 = ROL64((argA3^Di), 6)@
@d2 = ROL64((argA4^Do), 25)@
@d3 = ROL64((argA5^Du), 8)@
@argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
@argA2 = Be ^((~Bi)& Bo )@
@argA3 = Bi ^((~Bo)& Bu )@
@argA4 = Bo ^((~Bu)& Ba )@
@argA5 = Bu ^((~Ba)& Be )@
veor.64 \argA3, \argA3, d9
veor.64 \argA4, \argA4, d10
vshl.u64 d1, \argA3, #6
vldr.64 d6, [sp, #\argA1]
vshl.u64 d2, \argA4, #25
veor.64 \argA5, \argA5, d11
vsri.64 d1, \argA3, #64-6
veor.64 \argA2, \argA2, d8
vsri.64 d2, \argA4, #64-25
vext.8 d3, \argA5, \argA5, #7
veor.64 d6, d6, d7
vbic.64 \argA3, d2, d1
vadd.u64 d0, \argA2, \argA2
vbic.64 \argA4, d3, d2
vsri.64 d0, \argA2, #64-1
vshl.u64 d4, d6, #18
veor.64 \argA2, d1, \argA4
veor.64 \argA3, d0
vsri.64 d4, d6, #64-18
vstr.64 \argA3, [sp, #\argA1]
veor.64 d5, \argA3
vbic.64 \argA5, d1, d0
vbic.64 \argA3, d4, d3
vbic.64 \argA4, d0, d4
veor.64 \argA3, d2
veor.64 \argA4, d3
veor.64 \argA5, d4
.endm
.macro KeccakThetaRhoPiChi3 argA1, argA2, argA3, argA4, argA5
@d1 = ROL64((argA1^Da), 36)@
@d2 = ROL64((argA2^De), 10)@
@d3 = ROL64((argA3^Di), 15)@
@d4 = ROL64((argA4^Do), 56)@
@d0 = ROL64((argA5^Du), 27)@
@argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
@argA2 = Be ^((~Bi)& Bo )@
@argA3 = Bi ^((~Bo)& Bu )@
@argA4 = Bo ^((~Bu)& Ba )@
@argA5 = Bu ^((~Ba)& Be )@
veor.64 \argA2, \argA2, d8
veor.64 \argA3, \argA3, d9
vshl.u64 d2, \argA2, #10
vldr.64 d6, [sp, #\argA1]
vshl.u64 d3, \argA3, #15
veor.64 \argA4, \argA4, d10
vsri.64 d2, \argA2, #64-10
vsri.64 d3, \argA3, #64-15
veor.64 \argA5, \argA5, d11
vext.8 d4, \argA4, \argA4, #1
vbic.64 \argA2, d3, d2
vshl.u64 d0, \argA5, #27
veor.64 d6, d6, d7
vbic.64 \argA3, d4, d3
vsri.64 d0, \argA5, #64-27
vshl.u64 d1, d6, #36
veor.64 \argA3, d2
vbic.64 \argA4, d0, d4
vsri.64 d1, d6, #64-36
veor.64 \argA4, d3
vbic.64 d6, d2, d1
vbic.64 \argA5, d1, d0
veor.64 d6, d0
veor.64 \argA2, d1
vstr.64 d6, [sp, #\argA1]
veor.64 d5, d6
veor.64 \argA5, d4
.endm
.macro KeccakThetaRhoPiChi4 argA1, argA2, argA3, argA4, argA5
@d3 = ROL64((argA1^Da), 41)@
@d4 = ROL64((argA2^De), 2)@
@d0 = ROL64((argA3^Di), 62)@
@d1 = ROL64((argA4^Do), 55)@
@d2 = ROL64((argA5^Du), 39)@
@argA1 = Ba ^((~Be)& Bi )@ Ca ^= argA1@
@argA2 = Be ^((~Bi)& Bo )@
@argA3 = Bi ^((~Bo)& Bu )@
@argA4 = Bo ^((~Bu)& Ba )@
@argA5 = Bu ^((~Ba)& Be )@
veor.64 \argA2, \argA2, d8
veor.64 \argA3, \argA3, d9
vshl.u64 d4, \argA2, #2
veor.64 \argA5, \argA5, d11
vshl.u64 d0, \argA3, #62
vldr.64 d6, [sp, #\argA1]
vsri.64 d4, \argA2, #64-2
veor.64 \argA4, \argA4, d10
vsri.64 d0, \argA3, #64-62
vshl.u64 d1, \argA4, #55
veor.64 d6, d6, d7
vshl.u64 d2, \argA5, #39
vsri.64 d1, \argA4, #64-55
vbic.64 \argA4, d0, d4
vsri.64 d2, \argA5, #64-39
vbic.64 \argA2, d1, d0
vshl.u64 d3, d6, #41
veor.64 \argA5, d4, \argA2
vbic.64 \argA2, d2, d1
vsri.64 d3, d6, #64-41
veor.64 d6, d0, \argA2
vbic.64 \argA2, d3, d2
vbic.64 \argA3, d4, d3
veor.64 \argA2, d1
vstr.64 d6, [sp, #\argA1]
veor.64 d5, d6
veor.64 \argA3, d2
veor.64 \argA4, d3
.endm
@// --- constants
.align 8
.ltorg
KeccakF1600RoundConstantsWithTerminator:
.quad 0x0000000000000001
.quad 0x0000000000008082
.quad 0x800000000000808a
.quad 0x8000000080008000
.quad 0x000000000000808b
.quad 0x0000000080000001
.quad 0x8000000080008081
.quad 0x8000000000008009
.quad 0x000000000000008a
.quad 0x0000000000000088
.quad 0x0000000080008009
.quad 0x000000008000000a
.quad 0x000000008000808b
.quad 0x800000000000008b
.quad 0x8000000000008089
.quad 0x8000000000008003
.quad 0x8000000000008002
.quad 0x8000000000000080
.quad 0x000000000000800a
.quad 0x800000008000000a
.quad 0x8000000080008081
.quad 0x8000000000008080
.quad 0x0000000080000001
.quad 0x8000000080008008
.quad 0xFFFFFFFFFFFFFFFF @//terminator
.align 8
@// --- code
@not callable from C!
.global KeccakF_armv7a_neon_asm
KeccakF_armv7a_neon_asm: @
adr r3, KeccakF1600RoundConstantsWithTerminator
roundLoop:
KeccakThetaRhoPiChiIota Aba, d13, d19, d25, d31
KeccakThetaRhoPiChi1 Aka, d15, d21, d22, d28
KeccakThetaRhoPiChi2 Asa, d12, d18, d24, d30
KeccakThetaRhoPiChi3 Aga, d14, d20, d26, d27
KeccakThetaRhoPiChi4 Ama, d16, d17, d23, d29
KeccakThetaRhoPiChiIota Aba, d15, d18, d26, d29
KeccakThetaRhoPiChi1 Asa, d14, d17, d25, d28
KeccakThetaRhoPiChi2 Ama, d13, d21, d24, d27
KeccakThetaRhoPiChi3 Aka, d12, d20, d23, d31
KeccakThetaRhoPiChi4 Aga, d16, d19, d22, d30
KeccakThetaRhoPiChiIota Aba, d14, d21, d23, d30
KeccakThetaRhoPiChi1 Ama, d12, d19, d26, d28
KeccakThetaRhoPiChi2 Aga, d15, d17, d24, d31
KeccakThetaRhoPiChi3 Asa, d13, d20, d22, d29
KeccakThetaRhoPiChi4 Aka, d16, d18, d25, d27
KeccakThetaRhoPiChiIota Aba, d12, d17, d22, d27
KeccakThetaRhoPiChi1 Aga, d13, d18, d23, d28
KeccakThetaRhoPiChi2 Aka, d14, d19, d24, d29
ldr r0, [r3]
KeccakThetaRhoPiChi3 Ama, d15, d20, d25, d30
cmp r0, #0xFFFFFFFF
KeccakThetaRhoPiChi4 Asa, d16, d21, d26, d31
bne roundLoop
bx lr
@
.align 8
@//void KeccakF_armv7a( tKeccakLane * state ) callable from C
.global KeccakF_armv7a_neon
KeccakF_armv7a_neon: @
vpush {q4-q7}
sub sp,sp, #5*8
vldr.64 d0, [r0, #0*8]
vldr.64 d12, [r0, #1*8]
vldr.64 d17, [r0, #2*8]
vldr.64 d22, [r0, #3*8]
vldr.64 d27, [r0, #4*8]
vldr.64 d1, [r0, #5*8]
vldr.64 d13, [r0, #6*8]
vldr.64 d18, [r0, #7*8]
vldr.64 d23, [r0, #8*8]
vldr.64 d28, [r0, #9*8]
vldr.64 d2, [r0, #10*8]
vldr.64 d14, [r0, #11*8]
vldr.64 d19, [r0, #12*8]
vldr.64 d24, [r0, #13*8]
vldr.64 d29, [r0, #14*8]
vldr.64 d3, [r0, #15*8]
vldr.64 d15, [r0, #16*8]
vldr.64 d20, [r0, #17*8]
vldr.64 d25, [r0, #18*8]
vldr.64 d30, [r0, #19*8]
vldr.64 d4, [r0, #20*8]
vldr.64 d16, [r0, #21*8]
vldr.64 d21, [r0, #22*8]
vldr.64 d26, [r0, #23*8]
vldr.64 d31, [r0, #24*8]
vstr.64 d0, [sp, #Aba]
mov r2, lr
vstr.64 d1, [sp, #Aga]
veor.64 q0, q0, q1
vstr.64 d2, [sp, #Aka]
veor.64 d5, d0, d1
vstr.64 d3, [sp, #Ama]
mov r1, r0
vstr.64 d4, [sp, #Asa]
veor.64 d5, d5, d4
bl KeccakF_armv7a_neon_asm
vpop.64 { d0- d4 }
vstr.64 d0, [r1, #0*8]
vstr.64 d12, [r1, #1*8]
vstr.64 d17, [r1, #2*8]
vstr.64 d22, [r1, #3*8]
vstr.64 d27, [r1, #4*8]
vstr.64 d1, [r1, #5*8]
vstr.64 d13, [r1, #6*8]
vstr.64 d18, [r1, #7*8]
vstr.64 d23, [r1, #8*8]
vstr.64 d28, [r1, #9*8]
vstr.64 d2, [r1, #10*8]
vstr.64 d14, [r1, #11*8]
vstr.64 d19, [r1, #12*8]
vstr.64 d24, [r1, #13*8]
vstr.64 d29, [r1, #14*8]
vstr.64 d3, [r1, #15*8]
vstr.64 d15, [r1, #16*8]
vstr.64 d20, [r1, #17*8]
vstr.64 d25, [r1, #18*8]
vstr.64 d30, [r1, #19*8]
vstr.64 d4, [r1, #20*8]
vstr.64 d16, [r1, #21*8]
vstr.64 d21, [r1, #22*8]
vstr.64 d26, [r1, #23*8]
vstr.64 d31, [r1, #24*8]
vpop {q4-q7}
bx r2
@

View File

@ -1,4 +0,0 @@
#define Unrolling 2
//#define UseBebigokimisa
//#define UseInterleaveTables
#define UseSchedule 3

View File

@ -1,524 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <string.h>
#include "brg_endian.h"
#include "KeccakF-1600-opt32-settings.h"
#include "KeccakF-1600-interface.h"
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned int UINT32;
typedef unsigned long long int UINT64;
#ifdef UseInterleaveTables
int interleaveTablesBuilt = 0;
UINT16 interleaveTable[65536];
UINT16 deinterleaveTable[65536];
void buildInterleaveTables()
{
UINT32 i, j;
UINT16 x;
if (!interleaveTablesBuilt) {
for(i=0; i<65536; i++) {
x = 0;
for(j=0; j<16; j++) {
if (i & (1 << j))
x |= (1 << (j/2 + 8*(j%2)));
}
interleaveTable[i] = x;
deinterleaveTable[x] = (UINT16)i;
}
interleaveTablesBuilt = 1;
}
}
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
#define xor2bytesIntoInterleavedWords(even, odd, source, j) \
i##j = interleaveTable[((const UINT16*)source)[j]]; \
((UINT8*)even)[j] ^= i##j & 0xFF; \
((UINT8*)odd)[j] ^= i##j >> 8;
#define setInterleavedWordsInto2bytes(dest, even, odd, j) \
d##j = deinterleaveTable[((even >> (j*8)) & 0xFF) ^ (((odd >> (j*8)) & 0xFF) << 8)]; \
((UINT16*)dest)[j] = d##j;
#else // (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN)
#define xor2bytesIntoInterleavedWords(even, odd, source, j) \
i##j = interleaveTable[source[2*j] ^ ((UINT16)source[2*j+1] << 8)]; \
*even ^= (i##j & 0xFF) << (j*8); \
*odd ^= ((i##j >> 8) & 0xFF) << (j*8);
#define setInterleavedWordsInto2bytes(dest, even, odd, j) \
d##j = deinterleaveTable[((even >> (j*8)) & 0xFF) ^ (((odd >> (j*8)) & 0xFF) << 8)]; \
dest[2*j] = d##j & 0xFF; \
dest[2*j+1] = d##j >> 8;
#endif // Endianness
void xor8bytesIntoInterleavedWords(UINT32 *even, UINT32 *odd, const UINT8* source)
{
UINT16 i0, i1, i2, i3;
xor2bytesIntoInterleavedWords(even, odd, source, 0)
xor2bytesIntoInterleavedWords(even, odd, source, 1)
xor2bytesIntoInterleavedWords(even, odd, source, 2)
xor2bytesIntoInterleavedWords(even, odd, source, 3)
}
#define xorLanesIntoState(laneCount, state, input) \
{ \
int i; \
for(i=0; i<(laneCount); i++) \
xor8bytesIntoInterleavedWords(state+i*2, state+i*2+1, input+i*8); \
}
void setInterleavedWordsInto8bytes(UINT8* dest, UINT32 even, UINT32 odd)
{
UINT16 d0, d1, d2, d3;
setInterleavedWordsInto2bytes(dest, even, odd, 0)
setInterleavedWordsInto2bytes(dest, even, odd, 1)
setInterleavedWordsInto2bytes(dest, even, odd, 2)
setInterleavedWordsInto2bytes(dest, even, odd, 3)
}
#define extractLanes(laneCount, state, data) \
{ \
int i; \
for(i=0; i<(laneCount); i++) \
setInterleavedWordsInto8bytes(data+i*8, ((UINT32*)state)[i*2], ((UINT32*)state)[i*2+1]); \
}
#else // No interleaving tables
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
// Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
#define xorInterleavedLE(rateInLanes, state, input) \
{ \
const UINT32 * pI = (const UINT32 *)input; \
UINT32 * pS = state; \
UINT32 t, x0, x1; \
int i; \
for (i = (rateInLanes)-1; i >= 0; --i) \
{ \
x0 = *(pI++); \
t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1); \
t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2); \
t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4); \
t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8); \
x1 = *(pI++); \
t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1); \
t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2); \
t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4); \
t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8); \
*(pS++) ^= (UINT16)x0 | (x1 << 16); \
*(pS++) ^= (x0 >> 16) | (x1 & 0xFFFF0000); \
} \
}
#define xorLanesIntoState(laneCount, state, input) \
xorInterleavedLE(laneCount, state, input)
#else // (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN)
// Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
UINT64 toInterleaving(UINT64 x)
{
UINT64 t;
t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1);
t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16);
return x;
}
void xor8bytesIntoInterleavedWords(UINT32* evenAndOdd, const UINT8* source)
{
// This can be optimized
UINT64 sourceWord =
(UINT64)source[0]
^ (((UINT64)source[1]) << 8)
^ (((UINT64)source[2]) << 16)
^ (((UINT64)source[3]) << 24)
^ (((UINT64)source[4]) << 32)
^ (((UINT64)source[5]) << 40)
^ (((UINT64)source[6]) << 48)
^ (((UINT64)source[7]) << 56);
UINT64 evenAndOddWord = toInterleaving(sourceWord);
evenAndOdd[0] ^= (UINT32)evenAndOddWord;
evenAndOdd[1] ^= (UINT32)(evenAndOddWord >> 32);
}
#define xorLanesIntoState(laneCount, state, input) \
{ \
int i; \
for(i=0; i<(laneCount); i++) \
xor8bytesIntoInterleavedWords(state+i*2, input+i*8); \
}
#endif // Endianness
// Credit: Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002
UINT64 fromInterleaving(UINT64 x)
{
UINT64 t;
t = (x ^ (x >> 16)) & 0x00000000FFFF0000ULL; x = x ^ t ^ (t << 16);
t = (x ^ (x >> 8)) & 0x0000FF000000FF00ULL; x = x ^ t ^ (t << 8);
t = (x ^ (x >> 4)) & 0x00F000F000F000F0ULL; x = x ^ t ^ (t << 4);
t = (x ^ (x >> 2)) & 0x0C0C0C0C0C0C0C0CULL; x = x ^ t ^ (t << 2);
t = (x ^ (x >> 1)) & 0x2222222222222222ULL; x = x ^ t ^ (t << 1);
return x;
}
void setInterleavedWordsInto8bytes(UINT8* dest, UINT32* evenAndOdd)
{
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
((UINT64*)dest)[0] = fromInterleaving(*(UINT64*)evenAndOdd);
#else // (PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN)
// This can be optimized
UINT64 evenAndOddWord = (UINT64)evenAndOdd[0] ^ ((UINT64)evenAndOdd[1] << 32);
UINT64 destWord = fromInterleaving(evenAndOddWord);
dest[0] = destWord & 0xFF;
dest[1] = (destWord >> 8) & 0xFF;
dest[2] = (destWord >> 16) & 0xFF;
dest[3] = (destWord >> 24) & 0xFF;
dest[4] = (destWord >> 32) & 0xFF;
dest[5] = (destWord >> 40) & 0xFF;
dest[6] = (destWord >> 48) & 0xFF;
dest[7] = (destWord >> 56) & 0xFF;
#endif // Endianness
}
#define extractLanes(laneCount, state, data) \
{ \
int i; \
for(i=0; i<(laneCount); i++) \
setInterleavedWordsInto8bytes(data+i*8, (UINT32*)state+i*2); \
}
#endif // With or without interleaving tables
#if defined(_MSC_VER)
#define ROL32(a, offset) _rotl(a, offset)
#elif (defined (__arm__) && defined(__ARMCC_VERSION))
#define ROL32(a, offset) __ror(a, 32-(offset))
#else
#define ROL32(a, offset) ((((UINT32)a) << (offset)) ^ (((UINT32)a) >> (32-(offset))))
#endif
#include "KeccakF-1600-unrolling.macros"
#include "KeccakF-1600-32.macros"
#if (UseSchedule == 3)
#ifdef UseBebigokimisa
#error "No lane complementing with schedule 3."
#endif
#if (Unrolling != 2)
#error "Only unrolling 2 is supported by schedule 3."
#endif
void KeccakPermutationOnWords(UINT32 *state)
{
rounds
}
void KeccakPermutationOnWordsAfterXoring(UINT32 *state, const UINT8 *input, unsigned int laneCount)
{
xorLanesIntoState(laneCount, state, input)
rounds
}
#ifdef ProvideFast576
void KeccakPermutationOnWordsAfterXoring576bits(UINT32 *state, const UINT8 *input)
{
xorLanesIntoState(9, state, input)
rounds
}
#endif
#ifdef ProvideFast832
void KeccakPermutationOnWordsAfterXoring832bits(UINT32 *state, const UINT8 *input)
{
xorLanesIntoState(13, state, input)
rounds
}
#endif
#ifdef ProvideFast1024
void KeccakPermutationOnWordsAfterXoring1024bits(UINT32 *state, const UINT8 *input)
{
xorLanesIntoState(16, state, input)
rounds
}
#endif
#ifdef ProvideFast1088
void KeccakPermutationOnWordsAfterXoring1088bits(UINT32 *state, const UINT8 *input)
{
xorLanesIntoState(17, state, input)
rounds
}
#endif
#ifdef ProvideFast1152
void KeccakPermutationOnWordsAfterXoring1152bits(UINT32 *state, const UINT8 *input)
{
xorLanesIntoState(18, state, input)
rounds
}
#endif
#ifdef ProvideFast1344
void KeccakPermutationOnWordsAfterXoring1344bits(UINT32 *state, const UINT8 *input)
{
xorLanesIntoState(21, state, input)
rounds
}
#endif
#else // (Schedule != 3)
void KeccakPermutationOnWords(UINT32 *state)
{
declareABCDE
#if (Unrolling != 24)
unsigned int i;
#endif
copyFromState(A, state)
rounds
}
void KeccakPermutationOnWordsAfterXoring(UINT32 *state, const UINT8 *input, unsigned int laneCount)
{
declareABCDE
unsigned int i;
xorLanesIntoState(laneCount, state, input)
copyFromState(A, state)
rounds
}
#ifdef ProvideFast576
void KeccakPermutationOnWordsAfterXoring576bits(UINT32 *state, const UINT8 *input)
{
declareABCDE
unsigned int i;
xorLanesIntoState(9, state, input)
copyFromState(A, state)
rounds
}
#endif
#ifdef ProvideFast832
void KeccakPermutationOnWordsAfterXoring832bits(UINT32 *state, const UINT8 *input)
{
declareABCDE
unsigned int i;
xorLanesIntoState(13, state, input)
copyFromState(A, state)
rounds
}
#endif
#ifdef ProvideFast1024
void KeccakPermutationOnWordsAfterXoring1024bits(UINT32 *state, const UINT8 *input)
{
declareABCDE
unsigned int i;
xorLanesIntoState(16, state, input)
copyFromState(A, state)
rounds
}
#endif
#ifdef ProvideFast1088
void KeccakPermutationOnWordsAfterXoring1088bits(UINT32 *state, const UINT8 *input)
{
declareABCDE
unsigned int i;
xorLanesIntoState(17, state, input)
copyFromState(A, state)
rounds
}
#endif
#ifdef ProvideFast1152
void KeccakPermutationOnWordsAfterXoring1152bits(UINT32 *state, const UINT8 *input)
{
declareABCDE
unsigned int i;
xorLanesIntoState(18, state, input)
copyFromState(A, state)
rounds
}
#endif
#ifdef ProvideFast1344
void KeccakPermutationOnWordsAfterXoring1344bits(UINT32 *state, const UINT8 *input)
{
declareABCDE
unsigned int i;
xorLanesIntoState(21, state, input)
copyFromState(A, state)
rounds
}
#endif
#endif
void KeccakInitialize()
{
#ifdef UseInterleaveTables
buildInterleaveTables();
#endif
}
void KeccakInitializeState(unsigned char *state)
{
memset(state, 0, 200);
#ifdef UseBebigokimisa
((UINT32*)state)[ 2] = ~(UINT32)0;
((UINT32*)state)[ 3] = ~(UINT32)0;
((UINT32*)state)[ 4] = ~(UINT32)0;
((UINT32*)state)[ 5] = ~(UINT32)0;
((UINT32*)state)[16] = ~(UINT32)0;
((UINT32*)state)[17] = ~(UINT32)0;
((UINT32*)state)[24] = ~(UINT32)0;
((UINT32*)state)[25] = ~(UINT32)0;
((UINT32*)state)[34] = ~(UINT32)0;
((UINT32*)state)[35] = ~(UINT32)0;
((UINT32*)state)[40] = ~(UINT32)0;
((UINT32*)state)[41] = ~(UINT32)0;
#endif
}
void KeccakPermutation(unsigned char *state)
{
// We assume the state is always stored as interleaved 32-bit words
KeccakPermutationOnWords((UINT32*)state);
}
#ifdef ProvideFast576
void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring576bits((UINT32*)state, data);
}
#endif
#ifdef ProvideFast832
void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring832bits((UINT32*)state, data);
}
#endif
#ifdef ProvideFast1024
void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring1024bits((UINT32*)state, data);
}
#endif
#ifdef ProvideFast1088
void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring1088bits((UINT32*)state, data);
}
#endif
#ifdef ProvideFast1152
void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring1152bits((UINT32*)state, data);
}
#endif
#ifdef ProvideFast1344
void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationOnWordsAfterXoring1344bits((UINT32*)state, data);
}
#endif
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
{
KeccakPermutationOnWordsAfterXoring((UINT32*)state, data, laneCount);
}
#ifdef ProvideFast1024
void KeccakExtract1024bits(const unsigned char *state, unsigned char *data)
{
extractLanes(16, state, data)
#ifdef UseBebigokimisa
((UINT32*)data)[ 2] = ~((UINT32*)data)[ 2];
((UINT32*)data)[ 3] = ~((UINT32*)data)[ 3];
((UINT32*)data)[ 4] = ~((UINT32*)data)[ 4];
((UINT32*)data)[ 5] = ~((UINT32*)data)[ 5];
((UINT32*)data)[16] = ~((UINT32*)data)[16];
((UINT32*)data)[17] = ~((UINT32*)data)[17];
((UINT32*)data)[24] = ~((UINT32*)data)[24];
((UINT32*)data)[25] = ~((UINT32*)data)[25];
#endif
}
#endif
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
{
extractLanes(laneCount, state, data)
#ifdef UseBebigokimisa
if (laneCount > 1) {
((UINT32*)data)[ 2] = ~((UINT32*)data)[ 2];
((UINT32*)data)[ 3] = ~((UINT32*)data)[ 3];
if (laneCount > 2) {
((UINT32*)data)[ 4] = ~((UINT32*)data)[ 4];
((UINT32*)data)[ 5] = ~((UINT32*)data)[ 5];
if (laneCount > 8) {
((UINT32*)data)[16] = ~((UINT32*)data)[16];
((UINT32*)data)[17] = ~((UINT32*)data)[17];
if (laneCount > 12) {
((UINT32*)data)[24] = ~((UINT32*)data)[24];
((UINT32*)data)[25] = ~((UINT32*)data)[25];
if (laneCount > 17) {
((UINT32*)data)[34] = ~((UINT32*)data)[34];
((UINT32*)data)[35] = ~((UINT32*)data)[35];
if (laneCount > 20) {
((UINT32*)data)[40] = ~((UINT32*)data)[40];
((UINT32*)data)[41] = ~((UINT32*)data)[41];
}
}
}
}
}
}
#endif
}

View File

@ -174,7 +174,7 @@ ALIGN const UINT64 rot_39_41[2] = {39, 41};
#include "KeccakF-1600-unrolling.macros"
void KeccakPermutationOnWords(UINT64 *state)
static void KeccakPermutationOnWords(UINT64 *state)
{
declareABCDE
#if (Unrolling != 24)
@ -188,7 +188,7 @@ void KeccakPermutationOnWords(UINT64 *state)
#endif
}
void KeccakPermutationOnWordsAfterXoring(UINT64 *state, const UINT64 *input, unsigned int laneCount)
static void KeccakPermutationOnWordsAfterXoring(UINT64 *state, const UINT64 *input, unsigned int laneCount)
{
declareABCDE
#if (Unrolling != 24)
@ -206,7 +206,7 @@ void KeccakPermutationOnWordsAfterXoring(UINT64 *state, const UINT64 *input, uns
}
#ifdef ProvideFast576
void KeccakPermutationOnWordsAfterXoring576bits(UINT64 *state, const UINT64 *input)
static void KeccakPermutationOnWordsAfterXoring576bits(UINT64 *state, const UINT64 *input)
{
declareABCDE
#if (Unrolling != 24)
@ -222,7 +222,7 @@ void KeccakPermutationOnWordsAfterXoring576bits(UINT64 *state, const UINT64 *inp
#endif
#ifdef ProvideFast832
void KeccakPermutationOnWordsAfterXoring832bits(UINT64 *state, const UINT64 *input)
static void KeccakPermutationOnWordsAfterXoring832bits(UINT64 *state, const UINT64 *input)
{
declareABCDE
#if (Unrolling != 24)
@ -238,7 +238,7 @@ void KeccakPermutationOnWordsAfterXoring832bits(UINT64 *state, const UINT64 *inp
#endif
#ifdef ProvideFast1024
void KeccakPermutationOnWordsAfterXoring1024bits(UINT64 *state, const UINT64 *input)
static void KeccakPermutationOnWordsAfterXoring1024bits(UINT64 *state, const UINT64 *input)
{
declareABCDE
#if (Unrolling != 24)
@ -254,7 +254,7 @@ void KeccakPermutationOnWordsAfterXoring1024bits(UINT64 *state, const UINT64 *in
#endif
#ifdef ProvideFast1088
void KeccakPermutationOnWordsAfterXoring1088bits(UINT64 *state, const UINT64 *input)
static void KeccakPermutationOnWordsAfterXoring1088bits(UINT64 *state, const UINT64 *input)
{
declareABCDE
#if (Unrolling != 24)
@ -270,7 +270,7 @@ void KeccakPermutationOnWordsAfterXoring1088bits(UINT64 *state, const UINT64 *in
#endif
#ifdef ProvideFast1152
void KeccakPermutationOnWordsAfterXoring1152bits(UINT64 *state, const UINT64 *input)
static void KeccakPermutationOnWordsAfterXoring1152bits(UINT64 *state, const UINT64 *input)
{
declareABCDE
#if (Unrolling != 24)
@ -286,7 +286,7 @@ void KeccakPermutationOnWordsAfterXoring1152bits(UINT64 *state, const UINT64 *in
#endif
#ifdef ProvideFast1344
void KeccakPermutationOnWordsAfterXoring1344bits(UINT64 *state, const UINT64 *input)
static void KeccakPermutationOnWordsAfterXoring1344bits(UINT64 *state, const UINT64 *input)
{
declareABCDE
#if (Unrolling != 24)
@ -324,7 +324,7 @@ void KeccakPermutation(unsigned char *state)
KeccakPermutationOnWords((UINT64*)state);
}
void fromBytesToWord(UINT64 *word, const UINT8 *bytes)
static void fromBytesToWord(UINT64 *word, const UINT8 *bytes)
{
unsigned int i;
@ -443,7 +443,7 @@ void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int
#endif
}
void fromWordToBytes(UINT8 *bytes, const UINT64 word)
static void fromWordToBytes(UINT8 *bytes, const UINT64 word)
{
unsigned int i;

View File

@ -1,300 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <stdio.h>
#include <string.h>
#include "brg_endian.h"
#include "displayIntermediateValues.h"
#include "KeccakNISTInterface.h"
#include "KeccakF-1600-interface.h"
typedef unsigned char UINT8;
typedef unsigned long long int UINT64;
#define nrRounds 24
UINT64 KeccakRoundConstants[nrRounds];
#define nrLanes 25
unsigned int KeccakRhoOffsets[nrLanes];
void KeccakPermutationOnWords(UINT64 *state);
void theta(UINT64 *A);
void rho(UINT64 *A);
void pi(UINT64 *A);
void chi(UINT64 *A);
void iota(UINT64 *A, unsigned int indexRound);
void fromBytesToWords(UINT64 *stateAsWords, const unsigned char *state)
{
unsigned int i, j;
for(i=0; i<(KeccakPermutationSize/64); i++) {
stateAsWords[i] = 0;
for(j=0; j<(64/8); j++)
stateAsWords[i] |= (UINT64)(state[i*(64/8)+j]) << (8*j);
}
}
void fromWordsToBytes(unsigned char *state, const UINT64 *stateAsWords)
{
unsigned int i, j;
for(i=0; i<(KeccakPermutationSize/64); i++)
for(j=0; j<(64/8); j++)
state[i*(64/8)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;
}
void KeccakPermutation(unsigned char *state)
{
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
UINT64 stateAsWords[KeccakPermutationSize/64];
#endif
displayStateAsBytes(1, "Input of permutation", state);
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
KeccakPermutationOnWords((UINT64*)state);
#else
fromBytesToWords(stateAsWords, state);
KeccakPermutationOnWords(stateAsWords);
fromWordsToBytes(state, stateAsWords);
#endif
displayStateAsBytes(1, "State after permutation", state);
}
void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes)
{
unsigned int i;
for(i=0; i<dataLengthInBytes; i++)
state[i] ^= data[i];
KeccakPermutation(state);
}
void KeccakPermutationOnWords(UINT64 *state)
{
unsigned int i;
displayStateAs64bitWords(3, "Same, with lanes as 64-bit words", state);
for(i=0; i<nrRounds; i++) {
displayRoundNumber(3, i);
theta(state);
displayStateAs64bitWords(3, "After theta", state);
rho(state);
displayStateAs64bitWords(3, "After rho", state);
pi(state);
displayStateAs64bitWords(3, "After pi", state);
chi(state);
displayStateAs64bitWords(3, "After chi", state);
iota(state, i);
displayStateAs64bitWords(3, "After iota", state);
}
}
#define index(x, y) (((x)%5)+5*((y)%5))
#define ROL64(a, offset) ((offset != 0) ? ((((UINT64)a) << offset) ^ (((UINT64)a) >> (64-offset))) : a)
void theta(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5], D[5];
for(x=0; x<5; x++) {
C[x] = 0;
for(y=0; y<5; y++)
C[x] ^= A[index(x, y)];
}
for(x=0; x<5; x++)
D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
for(x=0; x<5; x++)
for(y=0; y<5; y++)
A[index(x, y)] ^= D[x];
}
void rho(UINT64 *A)
{
unsigned int x, y;
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
}
void pi(UINT64 *A)
{
unsigned int x, y;
UINT64 tempA[25];
for(x=0; x<5; x++) for(y=0; y<5; y++)
tempA[index(x, y)] = A[index(x, y)];
for(x=0; x<5; x++) for(y=0; y<5; y++)
A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
}
void chi(UINT64 *A)
{
unsigned int x, y;
UINT64 C[5];
for(y=0; y<5; y++) {
for(x=0; x<5; x++)
C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
for(x=0; x<5; x++)
A[index(x, y)] = C[x];
}
}
void iota(UINT64 *A, unsigned int indexRound)
{
A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
}
int LFSR86540(UINT8 *LFSR)
{
int result = ((*LFSR) & 0x01) != 0;
if (((*LFSR) & 0x80) != 0)
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
else
(*LFSR) <<= 1;
return result;
}
void KeccakInitializeRoundConstants()
{
UINT8 LFSRstate = 0x01;
unsigned int i, j, bitPosition;
for(i=0; i<nrRounds; i++) {
KeccakRoundConstants[i] = 0;
for(j=0; j<7; j++) {
bitPosition = (1<<j)-1; //2^j-1
if (LFSR86540(&LFSRstate))
KeccakRoundConstants[i] ^= (UINT64)1<<bitPosition;
}
}
}
void KeccakInitializeRhoOffsets()
{
unsigned int x, y, t, newX, newY;
KeccakRhoOffsets[index(0, 0)] = 0;
x = 1;
y = 0;
for(t=0; t<24; t++) {
KeccakRhoOffsets[index(x, y)] = ((t+1)*(t+2)/2) % 64;
newX = (0*x+1*y) % 5;
newY = (2*x+3*y) % 5;
x = newX;
y = newY;
}
}
void KeccakInitialize()
{
KeccakInitializeRoundConstants();
KeccakInitializeRhoOffsets();
}
void displayRoundConstants(FILE *f)
{
unsigned int i;
for(i=0; i<nrRounds; i++) {
fprintf(f, "RC[%02i][0][0] = ", i);
fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] >> 32));
fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i] & 0xFFFFFFFFULL));
fprintf(f, "\n");
}
fprintf(f, "\n");
}
void displayRhoOffsets(FILE *f)
{
unsigned int x, y;
for(y=0; y<5; y++) for(x=0; x<5; x++) {
fprintf(f, "RhoOffset[%i][%i] = ", x, y);
fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]);
fprintf(f, "\n");
}
fprintf(f, "\n");
}
void KeccakInitializeState(unsigned char *state)
{
memset(state, 0, KeccakPermutationSizeInBytes);
}
#ifdef ProvideFast576
void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 72);
}
#endif
#ifdef ProvideFast832
void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 104);
}
#endif
#ifdef ProvideFast1024
void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 128);
}
#endif
#ifdef ProvideFast1088
void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 136);
}
#endif
#ifdef ProvideFast1152
void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 144);
}
#endif
#ifdef ProvideFast1344
void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 168);
}
#endif
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
{
KeccakPermutationAfterXor(state, data, laneCount*8);
}
#ifdef ProvideFast1024
void KeccakExtract1024bits(const unsigned char *state, unsigned char *data)
{
memcpy(data, state, 128);
}
#endif
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
{
memcpy(data, state, laneCount*8);
}

View File

@ -1,20 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#ifndef _KeccakPermutationReference_h_
#define _KeccakPermutationReference_h_
void displayRoundConstants(FILE *f);
void displayRhoOffsets(FILE *f);
#endif

View File

@ -1,371 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by the designers,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <stdio.h>
#include <string.h>
#include "brg_endian.h"
#include "displayIntermediateValues.h"
#include "KeccakNISTInterface.h"
#include "KeccakF-1600-interface.h"
typedef unsigned char UINT8;
typedef unsigned int UINT32;
#define nrRounds 24
UINT32 KeccakRoundConstants[nrRounds][2];
#define nrLanes 25
unsigned int KeccakRhoOffsets[nrLanes];
void KeccakPermutationOnWords(UINT32 *state);
void theta(UINT32 *A);
void rho(UINT32 *A);
void pi(UINT32 *A);
void chi(UINT32 *A);
void iota(UINT32 *A, unsigned int indexRound);
void toBitInterleaving(UINT32 low, UINT32 high, UINT32 *even, UINT32 *odd)
{
unsigned int i;
*even = 0;
*odd = 0;
for(i=0; i<64; i++) {
unsigned int inBit;
if (i < 32)
inBit = (low >> i) & 1;
else
inBit = (high >> (i-32)) & 1;
if ((i % 2) == 0)
*even |= inBit << (i/2);
else
*odd |= inBit << ((i-1)/2);
}
}
void fromBitInterleaving(UINT32 even, UINT32 odd, UINT32 *low, UINT32 *high)
{
unsigned int i;
*low = 0;
*high = 0;
for(i=0; i<64; i++) {
unsigned int inBit;
if ((i % 2) == 0)
inBit = (even >> (i/2)) & 1;
else
inBit = (odd >> ((i-1)/2)) & 1;
if (i < 32)
*low |= inBit << i;
else
*high |= inBit << (i-32);
}
}
void fromBytesToWords(UINT32 *stateAsWords, const unsigned char *state)
{
unsigned int i, j;
UINT32 low, high;
UINT32 even, odd;
for(i=0; i<(KeccakPermutationSize/64); i++) {
low = 0;
high = 0;
for(j=0; j<(32/8); j++)
low |= (UINT32)(state[i*(64/8)+j]) << (8*j);
for(j=(32/8); j<(64/8); j++)
high |= (UINT32)(state[i*(64/8)+j]) << (8*j-32);
toBitInterleaving(low, high, &even, &odd);
stateAsWords[2*i+0] = even;
stateAsWords[2*i+1] = odd;
}
}
void fromWordsToBytes(unsigned char *state, const UINT32 *stateAsWords)
{
unsigned int i, j;
UINT32 low, high;
for(i=0; i<(KeccakPermutationSize/64); i++) {
fromBitInterleaving(stateAsWords[2*i+0], stateAsWords[2*i+1], &low, &high);
for(j=0; j<(32/8); j++)
state[i*(64/8)+j] = (low >> (8*j)) & 0xFF;
for(j=32/8; j<(64/8); j++)
state[i*(64/8)+j] = (high >> (8*j-32)) & 0xFF;
}
}
void KeccakPermutation(unsigned char *state)
{
UINT32 stateAsWords[KeccakPermutationSize/32];
displayStateAsBytes(1, "Input of permutation", state);
fromBytesToWords(stateAsWords, state);
KeccakPermutationOnWords(stateAsWords);
fromWordsToBytes(state, stateAsWords);
displayStateAsBytes(1, "State after permutation", state);
}
void KeccakPermutationAfterXor(unsigned char *state, const unsigned char *data, unsigned int dataLengthInBytes)
{
unsigned int i;
for(i=0; i<dataLengthInBytes; i++)
state[i] ^= data[i];
KeccakPermutation(state);
}
void KeccakPermutationOnWords(UINT32 *state)
{
unsigned int i;
displayStateAs32bitWords(3, "Same, with lanes as pairs of 32-bit words (bit interleaving)", state);
for(i=0; i<nrRounds; i++) {
displayRoundNumber(3, i);
theta(state);
displayStateAs32bitWords(3, "After theta", state);
rho(state);
displayStateAs32bitWords(3, "After rho", state);
pi(state);
displayStateAs32bitWords(3, "After pi", state);
chi(state);
displayStateAs32bitWords(3, "After chi", state);
iota(state, i);
displayStateAs32bitWords(3, "After iota", state);
}
}
#define index(x, y,z) ((((x)%5)+5*((y)%5))*2 + z)
#define ROL32(a, offset) ((offset != 0) ? ((((UINT32)a) << offset) ^ (((UINT32)a) >> (32-offset))) : a)
void ROL64(UINT32 inEven, UINT32 inOdd, UINT32 *outEven, UINT32 *outOdd, unsigned int offset)
{
if ((offset % 2) == 0) {
*outEven = ROL32(inEven, offset/2);
*outOdd = ROL32(inOdd, offset/2);
}
else {
*outEven = ROL32(inOdd, (offset+1)/2);
*outOdd = ROL32(inEven, (offset-1)/2);
}
}
void theta(UINT32 *A)
{
unsigned int x, y, z;
UINT32 C[5][2], D[5][2];
for(x=0; x<5; x++) {
for(z=0; z<2; z++) {
C[x][z] = 0;
for(y=0; y<5; y++)
C[x][z] ^= A[index(x, y, z)];
}
}
for(x=0; x<5; x++) {
ROL64(C[(x+1)%5][0], C[(x+1)%5][1], &(D[x][0]), &(D[x][1]), 1);
for(z=0; z<2; z++)
D[x][z] ^= C[(x+4)%5][z];
}
for(x=0; x<5; x++)
for(y=0; y<5; y++)
for(z=0; z<2; z++)
A[index(x, y, z)] ^= D[x][z];
}
void rho(UINT32 *A)
{
unsigned int x, y;
for(x=0; x<5; x++) for(y=0; y<5; y++)
ROL64(A[index(x, y, 0)], A[index(x, y, 1)], &(A[index(x, y, 0)]), &(A[index(x, y, 1)]), KeccakRhoOffsets[5*y+x]);
}
void pi(UINT32 *A)
{
unsigned int x, y, z;
UINT32 tempA[50];
for(x=0; x<5; x++) for(y=0; y<5; y++) for(z=0; z<2; z++)
tempA[index(x, y, z)] = A[index(x, y, z)];
for(x=0; x<5; x++) for(y=0; y<5; y++) for(z=0; z<2; z++)
A[index(0*x+1*y, 2*x+3*y, z)] = tempA[index(x, y, z)];
}
void chi(UINT32 *A)
{
unsigned int x, y, z;
UINT32 C[5][2];
for(y=0; y<5; y++) {
for(x=0; x<5; x++)
for(z=0; z<2; z++)
C[x][z] = A[index(x, y, z)] ^ ((~A[index(x+1, y, z)]) & A[index(x+2, y, z)]);
for(x=0; x<5; x++)
for(z=0; z<2; z++)
A[index(x, y, z)] = C[x][z];
}
}
void iota(UINT32 *A, unsigned int indexRound)
{
A[index(0, 0, 0)] ^= KeccakRoundConstants[indexRound][0];
A[index(0, 0, 1)] ^= KeccakRoundConstants[indexRound][1];
}
int LFSR86540(UINT8 *LFSR)
{
int result = ((*LFSR) & 0x01) != 0;
if (((*LFSR) & 0x80) != 0)
// Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
else
(*LFSR) <<= 1;
return result;
}
void KeccakInitializeRoundConstants()
{
UINT8 LFSRstate = 0x01;
unsigned int i, j, bitPosition;
UINT32 low, high;
for(i=0; i<nrRounds; i++) {
low = high = 0;
for(j=0; j<7; j++) {
bitPosition = (1<<j)-1; //2^j-1
if (LFSR86540(&LFSRstate)) {
if (bitPosition < 32)
low ^= (UINT32)1 << bitPosition;
else
high ^= (UINT32)1 << (bitPosition-32);
}
}
toBitInterleaving(low, high, &(KeccakRoundConstants[i][0]), &(KeccakRoundConstants[i][1]));
}
}
void KeccakInitializeRhoOffsets()
{
unsigned int x, y, t, newX, newY;
KeccakRhoOffsets[0] = 0;
x = 1;
y = 0;
for(t=0; t<24; t++) {
KeccakRhoOffsets[5*y+x] = ((t+1)*(t+2)/2) % 64;
newX = (0*x+1*y) % 5;
newY = (2*x+3*y) % 5;
x = newX;
y = newY;
}
}
void KeccakInitialize()
{
KeccakInitializeRoundConstants();
KeccakInitializeRhoOffsets();
}
void displayRoundConstants(FILE *f)
{
unsigned int i;
for(i=0; i<nrRounds; i++) {
fprintf(f, "RC[%02i][0][0] = ", i);
fprintf(f, "%08X:%08X", (unsigned int)(KeccakRoundConstants[i][0]), (unsigned int)(KeccakRoundConstants[i][1]));
fprintf(f, "\n");
}
fprintf(f, "\n");
}
void displayRhoOffsets(FILE *f)
{
unsigned int x, y;
for(y=0; y<5; y++) for(x=0; x<5; x++) {
fprintf(f, "RhoOffset[%i][%i] = ", x, y);
fprintf(f, "%2i", KeccakRhoOffsets[5*y+x]);
fprintf(f, "\n");
}
fprintf(f, "\n");
}
void KeccakInitializeState(unsigned char *state)
{
memset(state, 0, KeccakPermutationSizeInBytes);
}
#ifdef ProvideFast576
void KeccakAbsorb576bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 72);
}
#endif
#ifdef ProvideFast832
void KeccakAbsorb832bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 104);
}
#endif
#ifdef ProvideFast1024
void KeccakAbsorb1024bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 128);
}
#endif
#ifdef ProvideFast1088
void KeccakAbsorb1088bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 136);
}
#endif
#ifdef ProvideFast1152
void KeccakAbsorb1152bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 144);
}
#endif
#ifdef ProvideFast1344
void KeccakAbsorb1344bits(unsigned char *state, const unsigned char *data)
{
KeccakPermutationAfterXor(state, data, 168);
}
#endif
void KeccakAbsorb(unsigned char *state, const unsigned char *data, unsigned int laneCount)
{
KeccakPermutationAfterXor(state, data, laneCount*8);
}
#ifdef ProvideFast1024
void KeccakExtract1024bits(const unsigned char *state, unsigned char *data)
{
memcpy(data, state, 128);
}
#endif
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
{
memcpy(data, state, laneCount*8);
}

View File

@ -1,62 +0,0 @@
/*
The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
Michaël Peeters and Gilles Van Assche. For more information, feedback or
questions, please refer to our website: http://keccak.noekeon.org/
Implementation by Ronny Van Keer,
hereby denoted as "the implementer".
To the extent possible under law, the implementer has waived all copyright
and related or neighboring rights to the source code in this file.
http://creativecommons.org/publicdomain/zero/1.0/
*/
#include <string.h>
#include "KeccakF-1600-interface.h"
#define UseBebigokimisa
typedef unsigned char UINT8;
typedef unsigned long long int UINT64;
void KeccakInitialize()
{
}
void KeccakExtract(const unsigned char *state, unsigned char *data, unsigned int laneCount)
{
memcpy(data, state, laneCount*8);
#ifdef UseBebigokimisa
if (laneCount > 8)
{
((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1];
((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2];
((UINT64*)data)[ 8] = ~((UINT64*)data)[ 8];
if (laneCount > 12)
{
((UINT64*)data)[12] = ~((UINT64*)data)[12];
if (laneCount > 17)
{
((UINT64*)data)[17] = ~((UINT64*)data)[17];
if (laneCount > 20)
{
((UINT64*)data)[20] = ~((UINT64*)data)[20];
}
}
}
}
else
{
if (laneCount > 1)
{
((UINT64*)data)[ 1] = ~((UINT64*)data)[ 1];
if (laneCount > 2)
{
((UINT64*)data)[ 2] = ~((UINT64*)data)[ 2];
}
}
}
#endif
}

View File

@ -1,766 +0,0 @@
#
# The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
# Michaël Peeters and Gilles Van Assche. For more information, feedback or
# questions, please refer to our website: http://keccak.noekeon.org/
#
# Implementation by Ronny Van Keer,
# hereby denoted as "the implementer".
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
#
.text
#// --- defines
.equ UseSIMD, 1
.equ _ba, 0*8
.equ _be, 1*8
.equ _bi, 2*8
.equ _bo, 3*8
.equ _bu, 4*8
.equ _ga, 5*8
.equ _ge, 6*8
.equ _gi, 7*8
.equ _go, 8*8
.equ _gu, 9*8
.equ _ka, 10*8
.equ _ke, 11*8
.equ _ki, 12*8
.equ _ko, 13*8
.equ _ku, 14*8
.equ _ma, 15*8
.equ _me, 16*8
.equ _mi, 17*8
.equ _mo, 18*8
.equ _mu, 19*8
.equ _sa, 20*8
.equ _se, 21*8
.equ _si, 22*8
.equ _so, 23*8
.equ _su, 24*8
# arguments
.equ apState, %rdi
.equ apInput, %rsi
.equ aNbrWords, %rdx
# xor input into state section
.equ xpState, %r9
# round vars
.equ rT1, %rax
.equ rpState, %rdi
.equ rpStack, %rsp
.equ rDa, %rbx
.equ rDe, %rcx
.equ rDi, %rdx
.equ rDo, %r8
.equ rDu, %r9
.equ rBa, %r10
.equ rBe, %r11
.equ rBi, %r12
.equ rBo, %r13
.equ rBu, %r14
.equ rCa, %rsi
.equ rCe, %rbp
.equ rCi, rBi
.equ rCo, rBo
.equ rCu, %r15
.macro mKeccakRound iState, oState, rc, lastRound
movq rCe, rDa
rolq rDa
movq _bi(\iState), rCi
xorq _gi(\iState), rDi
xorq rCu, rDa
xorq _ki(\iState), rCi
xorq _mi(\iState), rDi
xorq rDi, rCi
movq rCi, rDe
rolq rDe
movq _bo(\iState), rCo
xorq _go(\iState), rDo
xorq rCa, rDe
xorq _ko(\iState), rCo
xorq _mo(\iState), rDo
xorq rDo, rCo
movq rCo, rDi
rolq rDi
movq rCu, rDo
xorq rCe, rDi
rolq rDo
movq rCa, rDu
xorq rCi, rDo
rolq rDu
movq _ba(\iState), rBa
movq _ge(\iState), rBe
xorq rCo, rDu
movq _ki(\iState), rBi
movq _mo(\iState), rBo
movq _su(\iState), rBu
xorq rDe, rBe
rolq $44, rBe
xorq rDi, rBi
xorq rDa, rBa
rolq $43, rBi
movq rBe, rCa
movq $\rc, rT1
orq rBi, rCa
xorq rBa, rT1
xorq rT1, rCa
movq rCa, _ba(\oState)
xorq rDu, rBu
rolq $14, rBu
movq rBa, rCu
andq rBe, rCu
xorq rBu, rCu
movq rCu, _bu(\oState)
xorq rDo, rBo
rolq $21, rBo
movq rBo, rT1
andq rBu, rT1
xorq rBi, rT1
movq rT1, _bi(\oState)
notq rBi
orq rBa, rBu
orq rBo, rBi
xorq rBo, rBu
xorq rBe, rBi
movq rBu, _bo(\oState)
movq rBi, _be(\oState)
.if \lastRound == 0
movq rBi, rCe
.endif
movq _gu(\iState), rBe
xorq rDu, rBe
movq _ka(\iState), rBi
rolq $20, rBe
xorq rDa, rBi
rolq $3, rBi
movq _bo(\iState), rBa
movq rBe, rT1
orq rBi, rT1
xorq rDo, rBa
movq _me(\iState), rBo
movq _si(\iState), rBu
rolq $28, rBa
xorq rBa, rT1
movq rT1, _ga(\oState)
.if \lastRound == 0
xor rT1, rCa
.endif
xorq rDe, rBo
rolq $45, rBo
movq rBi, rT1
andq rBo, rT1
xorq rBe, rT1
movq rT1, _ge(\oState)
.if \lastRound == 0
xorq rT1, rCe
.endif
xorq rDi, rBu
rolq $61, rBu
movq rBu, rT1
orq rBa, rT1
xorq rBo, rT1
movq rT1, _go(\oState)
andq rBe, rBa
xorq rBu, rBa
movq rBa, _gu(\oState)
notq rBu
.if \lastRound == 0
xorq rBa, rCu
.endif
orq rBu, rBo
xorq rBi, rBo
movq rBo, _gi(\oState)
movq _be(\iState), rBa
movq _gi(\iState), rBe
movq _ko(\iState), rBi
movq _mu(\iState), rBo
movq _sa(\iState), rBu
xorq rDi, rBe
rolq $6, rBe
xorq rDo, rBi
rolq $25, rBi
movq rBe, rT1
orq rBi, rT1
xorq rDe, rBa
rolq $1, rBa
xorq rBa, rT1
movq rT1, _ka(\oState)
.if \lastRound == 0
xor rT1, rCa
.endif
xorq rDu, rBo
rolq $8, rBo
movq rBi, rT1
andq rBo, rT1
xorq rBe, rT1
movq rT1, _ke(\oState)
.if \lastRound == 0
xorq rT1, rCe
.endif
xorq rDa, rBu
rolq $18, rBu
notq rBo
movq rBo, rT1
andq rBu, rT1
xorq rBi, rT1
movq rT1, _ki(\oState)
movq rBu, rT1
orq rBa, rT1
xorq rBo, rT1
movq rT1, _ko(\oState)
andq rBe, rBa
xorq rBu, rBa
movq rBa, _ku(\oState)
.if \lastRound == 0
xorq rBa, rCu
.endif
movq _ga(\iState), rBe
xorq rDa, rBe
movq _ke(\iState), rBi
rolq $36, rBe
xorq rDe, rBi
movq _bu(\iState), rBa
rolq $10, rBi
movq rBe, rT1
movq _mi(\iState), rBo
andq rBi, rT1
xorq rDu, rBa
movq _so(\iState), rBu
rolq $27, rBa
xorq rBa, rT1
movq rT1, _ma(\oState)
.if \lastRound == 0
xor rT1, rCa
.endif
xorq rDi, rBo
rolq $15, rBo
movq rBi, rT1
orq rBo, rT1
xorq rBe, rT1
movq rT1, _me(\oState)
.if \lastRound == 0
xorq rT1, rCe
.endif
xorq rDo, rBu
rolq $56, rBu
notq rBo
movq rBo, rT1
orq rBu, rT1
xorq rBi, rT1
movq rT1, _mi(\oState)
orq rBa, rBe
xorq rBu, rBe
movq rBe, _mu(\oState)
andq rBa, rBu
xorq rBo, rBu
movq rBu, _mo(\oState)
.if \lastRound == 0
xorq rBe, rCu
.endif
movq _bi(\iState), rBa
movq _go(\iState), rBe
movq _ku(\iState), rBi
xorq rDi, rBa
movq _ma(\iState), rBo
rolq $62, rBa
xorq rDo, rBe
movq _se(\iState), rBu
rolq $55, rBe
xorq rDu, rBi
movq rBa, rDu
xorq rDe, rBu
rolq $2, rBu
andq rBe, rDu
xorq rBu, rDu
movq rDu, _su(\oState)
rolq $39, rBi
.if \lastRound == 0
xorq rDu, rCu
.endif
notq rBe
xorq rDa, rBo
movq rBe, rDa
andq rBi, rDa
xorq rBa, rDa
movq rDa, _sa(\oState)
.if \lastRound == 0
xor rDa, rCa
.endif
rolq $41, rBo
movq rBi, rDe
orq rBo, rDe
xorq rBe, rDe
movq rDe, _se(\oState)
.if \lastRound == 0
xorq rDe, rCe
.endif
movq rBo, rDi
movq rBu, rDo
andq rBu, rDi
orq rBa, rDo
xorq rBi, rDi
xorq rBo, rDo
movq rDi, _si(\oState)
movq rDo, _so(\oState)
.endm
.macro mKeccakPermutation
subq $8*25, %rsp
movq _ba(rpState), rCa
movq _be(rpState), rCe
movq _bu(rpState), rCu
xorq _ga(rpState), rCa
xorq _ge(rpState), rCe
xorq _gu(rpState), rCu
xorq _ka(rpState), rCa
xorq _ke(rpState), rCe
xorq _ku(rpState), rCu
xorq _ma(rpState), rCa
xorq _me(rpState), rCe
xorq _mu(rpState), rCu
xorq _sa(rpState), rCa
xorq _se(rpState), rCe
movq _si(rpState), rDi
movq _so(rpState), rDo
xorq _su(rpState), rCu
mKeccakRound rpState, rpStack, 0x0000000000000001, 0
mKeccakRound rpStack, rpState, 0x0000000000008082, 0
mKeccakRound rpState, rpStack, 0x800000000000808a, 0
mKeccakRound rpStack, rpState, 0x8000000080008000, 0
mKeccakRound rpState, rpStack, 0x000000000000808b, 0
mKeccakRound rpStack, rpState, 0x0000000080000001, 0
mKeccakRound rpState, rpStack, 0x8000000080008081, 0
mKeccakRound rpStack, rpState, 0x8000000000008009, 0
mKeccakRound rpState, rpStack, 0x000000000000008a, 0
mKeccakRound rpStack, rpState, 0x0000000000000088, 0
mKeccakRound rpState, rpStack, 0x0000000080008009, 0
mKeccakRound rpStack, rpState, 0x000000008000000a, 0
mKeccakRound rpState, rpStack, 0x000000008000808b, 0
mKeccakRound rpStack, rpState, 0x800000000000008b, 0
mKeccakRound rpState, rpStack, 0x8000000000008089, 0
mKeccakRound rpStack, rpState, 0x8000000000008003, 0
mKeccakRound rpState, rpStack, 0x8000000000008002, 0
mKeccakRound rpStack, rpState, 0x8000000000000080, 0
mKeccakRound rpState, rpStack, 0x000000000000800a, 0
mKeccakRound rpStack, rpState, 0x800000008000000a, 0
mKeccakRound rpState, rpStack, 0x8000000080008081, 0
mKeccakRound rpStack, rpState, 0x8000000000008080, 0
mKeccakRound rpState, rpStack, 0x0000000080000001, 0
mKeccakRound rpStack, rpState, 0x8000000080008008, 1
addq $8*25, %rsp
.endm
.macro mPushRegs
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
.endm
.macro mPopRegs
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbp
popq %rbx
.endm
.macro mXorState128 input, state, offset
.if UseSIMD == 0
movq \offset(\input), %rax
movq \offset+8(\input), %rcx
xorq %rax, \offset(\state)
xorq %rcx, \offset+8(\state)
.else
movdqu \offset(\input), %xmm0
pxor \offset(\state), %xmm0
movdqu %xmm0, \offset(\state)
.endif
.endm
.macro mXorState256 input, state, offset
.if UseSIMD == 0
movq \offset(\input), %rax
movq \offset+8(\input), %r10
movq \offset+16(\input), %rcx
movq \offset+24(\input), %r8
xorq %rax, \offset(\state)
xorq %r10, \offset+8(\state)
xorq %rcx, \offset+16(\state)
xorq %r8, \offset+24(\state)
.else
movdqu \offset(\input), %xmm0
pxor \offset(\state), %xmm0
movdqu \offset+16(\input), %xmm1
pxor \offset+16(\state), %xmm1
movdqu %xmm0, \offset(\state)
movdqu %xmm1, \offset+16(\state)
.endif
.endm
.macro mXorState512 input, state, offset
.if UseSIMD == 0
mXorState256 \input, \state, \offset
mXorState256 \input, \state, \offset+32
.else
movdqu \offset(\input), %xmm0
movdqu \offset+16(\input), %xmm1
pxor \offset(\state), %xmm0
movdqu \offset+32(\input), %xmm2
pxor \offset+16(\state), %xmm1
movdqu %xmm0, \offset(\state)
movdqu \offset+48(\input), %xmm3
pxor \offset+32(\state), %xmm2
movdqu %xmm1, \offset+16(\state)
pxor \offset+48(\state), %xmm3
movdqu %xmm2, \offset+32(\state)
movdqu %xmm3, \offset+48(\state)
.endif
.endm
# -------------------------------------------------------------------------
.size KeccakPermutation, .-KeccakPermutation
.align 2
.global KeccakPermutation
.type KeccakPermutation, %function
KeccakPermutation:
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb576bits, .-KeccakAbsorb576bits
.align 2
.global KeccakAbsorb576bits
.type KeccakAbsorb576bits, %function
KeccakAbsorb576bits:
mXorState512 apInput, apState, 0
movq 64(apInput), %rax
xorq %rax, 64(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb832bits, .-KeccakAbsorb832bits
.align 2
.global KeccakAbsorb832bits
.type KeccakAbsorb832bits, %function
KeccakAbsorb832bits:
mXorState512 apInput, apState, 0
mXorState256 apInput, apState, 64
movq 96(apInput), %rax
xorq %rax, 96(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1024bits, .-KeccakAbsorb1024bits
.align 2
.global KeccakAbsorb1024bits
.type KeccakAbsorb1024bits, %function
KeccakAbsorb1024bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1088bits, .-KeccakAbsorb1088bits
.align 2
.global KeccakAbsorb1088bits
.type KeccakAbsorb1088bits, %function
KeccakAbsorb1088bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
movq 128(apInput), %rax
xorq %rax, 128(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1152bits, .-KeccakAbsorb1152bits
.align 2
.global KeccakAbsorb1152bits
.type KeccakAbsorb1152bits, %function
KeccakAbsorb1152bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
mXorState128 apInput, apState, 128
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1344bits, .-KeccakAbsorb1344bits
.align 2
.global KeccakAbsorb1344bits
.type KeccakAbsorb1344bits, %function
KeccakAbsorb1344bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
mXorState256 apInput, apState, 128
movq 160(apInput), %rax
xorq %rax, 160(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb, .-KeccakAbsorb
.align 2
.global KeccakAbsorb
.type KeccakAbsorb, %function
KeccakAbsorb:
movq apState, xpState
test $16, aNbrWords
jz xorInputToState8
mXorState512 apInput, xpState, 0
mXorState512 apInput, xpState, 64
addq $128, apInput
addq $128, xpState
xorInputToState8:
test $8, aNbrWords
jz xorInputToState4
mXorState512 apInput, xpState, 0
addq $64, apInput
addq $64, xpState
xorInputToState4:
test $4, aNbrWords
jz xorInputToState2
mXorState256 apInput, xpState, 0
addq $32, apInput
addq $32, xpState
xorInputToState2:
test $2, aNbrWords
jz xorInputToState1
mXorState128 apInput, xpState, 0
addq $16, apInput
addq $16, xpState
xorInputToState1:
test $1, aNbrWords
jz xorInputToStateDone
movq (apInput), %rax
xorq %rax, (xpState)
xorInputToStateDone:
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakInitializeState, .-KeccakInitializeState
.align 2
.global KeccakInitializeState
.type KeccakInitializeState, %function
KeccakInitializeState:
xorq %rax, %rax
xorq %rcx, %rcx
notq %rcx
.if UseSIMD == 0
movq %rax, 0*8(apState)
movq %rcx, 1*8(apState)
movq %rcx, 2*8(apState)
movq %rax, 3*8(apState)
movq %rax, 4*8(apState)
movq %rax, 5*8(apState)
movq %rax, 6*8(apState)
movq %rax, 7*8(apState)
movq %rcx, 8*8(apState)
movq %rax, 9*8(apState)
movq %rax, 10*8(apState)
movq %rax, 11*8(apState)
movq %rcx, 12*8(apState)
movq %rax, 13*8(apState)
movq %rax, 14*8(apState)
movq %rax, 15*8(apState)
movq %rax, 16*8(apState)
movq %rcx, 17*8(apState)
movq %rax, 18*8(apState)
movq %rax, 19*8(apState)
movq %rcx, 20*8(apState)
movq %rax, 21*8(apState)
movq %rax, 22*8(apState)
movq %rax, 23*8(apState)
movq %rax, 24*8(apState)
.else
pxor %xmm0, %xmm0
movq %rax, 0*8(apState)
movq %rcx, 1*8(apState)
movq %rcx, 2*8(apState)
movq %rax, 3*8(apState)
movdqu %xmm0, 4*8(apState)
movdqu %xmm0, 6*8(apState)
movq %rcx, 8*8(apState)
movq %rax, 9*8(apState)
movdqu %xmm0, 10*8(apState)
movq %rcx, 12*8(apState)
movq %rax, 13*8(apState)
movdqu %xmm0, 14*8(apState)
movq %rax, 16*8(apState)
movq %rcx, 17*8(apState)
movdqu %xmm0, 18*8(apState)
movq %rcx, 20*8(apState)
movq %rax, 21*8(apState)
movdqu %xmm0, 22*8(apState)
movq %rax, 24*8(apState)
.endif
ret
# -------------------------------------------------------------------------
.size KeccakExtract1024bits, .-KeccakExtract1024bits
.align 2
.global KeccakExtract1024bits
.type KeccakExtract1024bits, %function
KeccakExtract1024bits:
movq 0*8(apState), %rax
movq 1*8(apState), %rcx
movq 2*8(apState), %rdx
movq 3*8(apState), %r8
notq %rcx
notq %rdx
movq %rax, 0*8(%rsi)
movq %rcx, 1*8(%rsi)
movq %rdx, 2*8(%rsi)
movq %r8, 3*8(%rsi)
movq 4*8(apState), %rax
movq 5*8(apState), %rcx
movq 6*8(apState), %rdx
movq 7*8(apState), %r8
movq %rax, 4*8(%rsi)
movq %rcx, 5*8(%rsi)
movq %rdx, 6*8(%rsi)
movq %r8, 7*8(%rsi)
movq 8*8(apState), %rax
movq 9*8(apState), %rcx
movq 10*8(apState), %rdx
movq 11*8(apState), %r8
notq %rax
movq %rax, 8*8(%rsi)
movq %rcx, 9*8(%rsi)
movq %rdx, 10*8(%rsi)
movq %r8, 11*8(%rsi)
movq 12*8(apState), %rax
movq 13*8(apState), %rcx
movq 14*8(apState), %rdx
movq 15*8(apState), %r8
notq %rax
movq %rax, 12*8(%rsi)
movq %rcx, 13*8(%rsi)
movq %rdx, 14*8(%rsi)
movq %r8, 15*8(%rsi)
ret

View File

@ -1,766 +0,0 @@
#
# The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
# Michaël Peeters and Gilles Van Assche. For more information, feedback or
# questions, please refer to our website: http://keccak.noekeon.org/
#
# Implementation by Ronny Van Keer,
# hereby denoted as "the implementer".
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
#
.text
#// --- defines
.equ UseSIMD, 1
.equ _ba, 0*8
.equ _be, 1*8
.equ _bi, 2*8
.equ _bo, 3*8
.equ _bu, 4*8
.equ _ga, 5*8
.equ _ge, 6*8
.equ _gi, 7*8
.equ _go, 8*8
.equ _gu, 9*8
.equ _ka, 10*8
.equ _ke, 11*8
.equ _ki, 12*8
.equ _ko, 13*8
.equ _ku, 14*8
.equ _ma, 15*8
.equ _me, 16*8
.equ _mi, 17*8
.equ _mo, 18*8
.equ _mu, 19*8
.equ _sa, 20*8
.equ _se, 21*8
.equ _si, 22*8
.equ _so, 23*8
.equ _su, 24*8
# arguments
.equ apState, %rdi
.equ apInput, %rsi
.equ aNbrWords, %rdx
# xor input into state section
.equ xpState, %r9
# round vars
.equ rT1, %rax
.equ rpState, %rdi
.equ rpStack, %rsp
.equ rDa, %rbx
.equ rDe, %rcx
.equ rDi, %rdx
.equ rDo, %r8
.equ rDu, %r9
.equ rBa, %r10
.equ rBe, %r11
.equ rBi, %r12
.equ rBo, %r13
.equ rBu, %r14
.equ rCa, %rsi
.equ rCe, %rbp
.equ rCi, rBi
.equ rCo, rBo
.equ rCu, %r15
.macro mKeccakRound iState, oState, rc, lastRound
movq rCe, rDa
shld $1, rDa, rDa
movq _bi(\iState), rCi
xorq _gi(\iState), rDi
xorq _ki(\iState), rCi
xorq rCu, rDa
xorq _mi(\iState), rDi
xorq rDi, rCi
movq rCi, rDe
shld $1, rDe, rDe
movq _bo(\iState), rCo
xorq _go(\iState), rDo
xorq _ko(\iState), rCo
xorq rCa, rDe
xorq _mo(\iState), rDo
xorq rDo, rCo
movq rCo, rDi
shld $1, rDi, rDi
movq rCu, rDo
xorq rCe, rDi
shld $1, rDo, rDo
movq rCa, rDu
xorq rCi, rDo
shld $1, rDu, rDu
movq _ba(\iState), rBa
movq _ge(\iState), rBe
xorq rCo, rDu
movq _ki(\iState), rBi
movq _mo(\iState), rBo
movq _su(\iState), rBu
xorq rDe, rBe
shld $44, rBe, rBe
xorq rDi, rBi
xorq rDa, rBa
shld $43, rBi, rBi
movq rBe, rCa
movq $\rc, rT1
orq rBi, rCa
xorq rBa, rT1
xorq rT1, rCa
movq rCa, _ba(\oState)
xorq rDu, rBu
shld $14, rBu, rBu
movq rBa, rCu
andq rBe, rCu
xorq rBu, rCu
movq rCu, _bu(\oState)
xorq rDo, rBo
shld $21, rBo, rBo
movq rBo, rT1
andq rBu, rT1
xorq rBi, rT1
movq rT1, _bi(\oState)
notq rBi
orq rBa, rBu
orq rBo, rBi
xorq rBo, rBu
xorq rBe, rBi
movq rBu, _bo(\oState)
movq rBi, _be(\oState)
.if \lastRound == 0
movq rBi, rCe
.endif
movq _gu(\iState), rBe
xorq rDu, rBe
movq _ka(\iState), rBi
shld $20, rBe, rBe
xorq rDa, rBi
shld $3, rBi, rBi
movq _bo(\iState), rBa
movq rBe, rT1
orq rBi, rT1
xorq rDo, rBa
movq _me(\iState), rBo
movq _si(\iState), rBu
shld $28, rBa, rBa
xorq rBa, rT1
movq rT1, _ga(\oState)
.if \lastRound == 0
xor rT1, rCa
.endif
xorq rDe, rBo
shld $45, rBo, rBo
movq rBi, rT1
andq rBo, rT1
xorq rBe, rT1
movq rT1, _ge(\oState)
.if \lastRound == 0
xorq rT1, rCe
.endif
xorq rDi, rBu
shld $61, rBu, rBu
movq rBu, rT1
orq rBa, rT1
xorq rBo, rT1
movq rT1, _go(\oState)
andq rBe, rBa
xorq rBu, rBa
movq rBa, _gu(\oState)
notq rBu
.if \lastRound == 0
xorq rBa, rCu
.endif
orq rBu, rBo
xorq rBi, rBo
movq rBo, _gi(\oState)
movq _be(\iState), rBa
movq _gi(\iState), rBe
movq _ko(\iState), rBi
movq _mu(\iState), rBo
movq _sa(\iState), rBu
xorq rDi, rBe
shld $6, rBe, rBe
xorq rDo, rBi
shld $25, rBi, rBi
movq rBe, rT1
orq rBi, rT1
xorq rDe, rBa
shld $1, rBa, rBa
xorq rBa, rT1
movq rT1, _ka(\oState)
.if \lastRound == 0
xor rT1, rCa
.endif
xorq rDu, rBo
shld $8, rBo, rBo
movq rBi, rT1
andq rBo, rT1
xorq rBe, rT1
movq rT1, _ke(\oState)
.if \lastRound == 0
xorq rT1, rCe
.endif
xorq rDa, rBu
shld $18, rBu, rBu
notq rBo
movq rBo, rT1
andq rBu, rT1
xorq rBi, rT1
movq rT1, _ki(\oState)
movq rBu, rT1
orq rBa, rT1
xorq rBo, rT1
movq rT1, _ko(\oState)
andq rBe, rBa
xorq rBu, rBa
movq rBa, _ku(\oState)
.if \lastRound == 0
xorq rBa, rCu
.endif
movq _ga(\iState), rBe
xorq rDa, rBe
movq _ke(\iState), rBi
shld $36, rBe, rBe
xorq rDe, rBi
movq _bu(\iState), rBa
shld $10, rBi, rBi
movq rBe, rT1
movq _mi(\iState), rBo
andq rBi, rT1
xorq rDu, rBa
movq _so(\iState), rBu
shld $27, rBa, rBa
xorq rBa, rT1
movq rT1, _ma(\oState)
.if \lastRound == 0
xor rT1, rCa
.endif
xorq rDi, rBo
shld $15, rBo, rBo
movq rBi, rT1
orq rBo, rT1
xorq rBe, rT1
movq rT1, _me(\oState)
.if \lastRound == 0
xorq rT1, rCe
.endif
xorq rDo, rBu
shld $56, rBu, rBu
notq rBo
movq rBo, rT1
orq rBu, rT1
xorq rBi, rT1
movq rT1, _mi(\oState)
orq rBa, rBe
xorq rBu, rBe
movq rBe, _mu(\oState)
andq rBa, rBu
xorq rBo, rBu
movq rBu, _mo(\oState)
.if \lastRound == 0
xorq rBe, rCu
.endif
movq _bi(\iState), rBa
movq _go(\iState), rBe
movq _ku(\iState), rBi
xorq rDi, rBa
movq _ma(\iState), rBo
shld $62, rBa, rBa
xorq rDo, rBe
movq _se(\iState), rBu
shld $55, rBe, rBe
xorq rDu, rBi
movq rBa, rDu
xorq rDe, rBu
shld $2, rBu, rBu
andq rBe, rDu
xorq rBu, rDu
movq rDu, _su(\oState)
shld $39, rBi, rBi
.if \lastRound == 0
xorq rDu, rCu
.endif
notq rBe
xorq rDa, rBo
movq rBe, rDa
andq rBi, rDa
xorq rBa, rDa
movq rDa, _sa(\oState)
.if \lastRound == 0
xor rDa, rCa
.endif
shld $41, rBo, rBo
movq rBi, rDe
orq rBo, rDe
xorq rBe, rDe
movq rDe, _se(\oState)
.if \lastRound == 0
xorq rDe, rCe
.endif
movq rBo, rDi
movq rBu, rDo
andq rBu, rDi
orq rBa, rDo
xorq rBi, rDi
xorq rBo, rDo
movq rDi, _si(\oState)
movq rDo, _so(\oState)
.endm
.macro mKeccakPermutation
subq $8*25, %rsp
movq _ba(rpState), rCa
movq _be(rpState), rCe
movq _bu(rpState), rCu
xorq _ga(rpState), rCa
xorq _ge(rpState), rCe
xorq _gu(rpState), rCu
xorq _ka(rpState), rCa
xorq _ke(rpState), rCe
xorq _ku(rpState), rCu
xorq _ma(rpState), rCa
xorq _me(rpState), rCe
xorq _mu(rpState), rCu
xorq _sa(rpState), rCa
xorq _se(rpState), rCe
movq _si(rpState), rDi
movq _so(rpState), rDo
xorq _su(rpState), rCu
mKeccakRound rpState, rpStack, 0x0000000000000001, 0
mKeccakRound rpStack, rpState, 0x0000000000008082, 0
mKeccakRound rpState, rpStack, 0x800000000000808a, 0
mKeccakRound rpStack, rpState, 0x8000000080008000, 0
mKeccakRound rpState, rpStack, 0x000000000000808b, 0
mKeccakRound rpStack, rpState, 0x0000000080000001, 0
mKeccakRound rpState, rpStack, 0x8000000080008081, 0
mKeccakRound rpStack, rpState, 0x8000000000008009, 0
mKeccakRound rpState, rpStack, 0x000000000000008a, 0
mKeccakRound rpStack, rpState, 0x0000000000000088, 0
mKeccakRound rpState, rpStack, 0x0000000080008009, 0
mKeccakRound rpStack, rpState, 0x000000008000000a, 0
mKeccakRound rpState, rpStack, 0x000000008000808b, 0
mKeccakRound rpStack, rpState, 0x800000000000008b, 0
mKeccakRound rpState, rpStack, 0x8000000000008089, 0
mKeccakRound rpStack, rpState, 0x8000000000008003, 0
mKeccakRound rpState, rpStack, 0x8000000000008002, 0
mKeccakRound rpStack, rpState, 0x8000000000000080, 0
mKeccakRound rpState, rpStack, 0x000000000000800a, 0
mKeccakRound rpStack, rpState, 0x800000008000000a, 0
mKeccakRound rpState, rpStack, 0x8000000080008081, 0
mKeccakRound rpStack, rpState, 0x8000000000008080, 0
mKeccakRound rpState, rpStack, 0x0000000080000001, 0
mKeccakRound rpStack, rpState, 0x8000000080008008, 1
addq $8*25, %rsp
.endm
.macro mPushRegs
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
.endm
.macro mPopRegs
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbp
popq %rbx
.endm
.macro mXorState128 input, state, offset
.if UseSIMD == 0
movq \offset(\input), %rax
movq \offset+8(\input), %rcx
xorq %rax, \offset(\state)
xorq %rcx, \offset+8(\state)
.else
movdqu \offset(\input), %xmm0
pxor \offset(\state), %xmm0
movdqu %xmm0, \offset(\state)
.endif
.endm
.macro mXorState256 input, state, offset
.if UseSIMD == 0
movq \offset(\input), %rax
movq \offset+8(\input), %r10
movq \offset+16(\input), %rcx
movq \offset+24(\input), %r8
xorq %rax, \offset(\state)
xorq %r10, \offset+8(\state)
xorq %rcx, \offset+16(\state)
xorq %r8, \offset+24(\state)
.else
movdqu \offset(\input), %xmm0
pxor \offset(\state), %xmm0
movdqu \offset+16(\input), %xmm1
pxor \offset+16(\state), %xmm1
movdqu %xmm0, \offset(\state)
movdqu %xmm1, \offset+16(\state)
.endif
.endm
.macro mXorState512 input, state, offset
.if UseSIMD == 0
mXorState256 \input, \state, \offset
mXorState256 \input, \state, \offset+32
.else
movdqu \offset(\input), %xmm0
movdqu \offset+16(\input), %xmm1
pxor \offset(\state), %xmm0
movdqu \offset+32(\input), %xmm2
pxor \offset+16(\state), %xmm1
movdqu %xmm0, \offset(\state)
movdqu \offset+48(\input), %xmm3
pxor \offset+32(\state), %xmm2
movdqu %xmm1, \offset+16(\state)
pxor \offset+48(\state), %xmm3
movdqu %xmm2, \offset+32(\state)
movdqu %xmm3, \offset+48(\state)
.endif
.endm
# -------------------------------------------------------------------------
.size KeccakPermutation, .-KeccakPermutation
.align 2
.global KeccakPermutation
.type KeccakPermutation, %function
KeccakPermutation:
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb576bits, .-KeccakAbsorb576bits
.align 2
.global KeccakAbsorb576bits
.type KeccakAbsorb576bits, %function
KeccakAbsorb576bits:
mXorState512 apInput, apState, 0
movq 64(apInput), %rax
xorq %rax, 64(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb832bits, .-KeccakAbsorb832bits
.align 2
.global KeccakAbsorb832bits
.type KeccakAbsorb832bits, %function
KeccakAbsorb832bits:
mXorState512 apInput, apState, 0
mXorState256 apInput, apState, 64
movq 96(apInput), %rax
xorq %rax, 96(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1024bits, .-KeccakAbsorb1024bits
.align 2
.global KeccakAbsorb1024bits
.type KeccakAbsorb1024bits, %function
KeccakAbsorb1024bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1088bits, .-KeccakAbsorb1088bits
.align 2
.global KeccakAbsorb1088bits
.type KeccakAbsorb1088bits, %function
KeccakAbsorb1088bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
movq 128(apInput), %rax
xorq %rax, 128(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1152bits, .-KeccakAbsorb1152bits
.align 2
.global KeccakAbsorb1152bits
.type KeccakAbsorb1152bits, %function
KeccakAbsorb1152bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
mXorState128 apInput, apState, 128
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb1344bits, .-KeccakAbsorb1344bits
.align 2
.global KeccakAbsorb1344bits
.type KeccakAbsorb1344bits, %function
KeccakAbsorb1344bits:
mXorState512 apInput, apState, 0
mXorState512 apInput, apState, 64
mXorState256 apInput, apState, 128
movq 160(apInput), %rax
xorq %rax, 160(apState)
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakAbsorb, .-KeccakAbsorb
.align 2
.global KeccakAbsorb
.type KeccakAbsorb, %function
KeccakAbsorb:
movq apState, xpState
test $16, aNbrWords
jz xorInputToState8
mXorState512 apInput, xpState, 0
mXorState512 apInput, xpState, 64
addq $128, apInput
addq $128, xpState
xorInputToState8:
test $8, aNbrWords
jz xorInputToState4
mXorState512 apInput, xpState, 0
addq $64, apInput
addq $64, xpState
xorInputToState4:
test $4, aNbrWords
jz xorInputToState2
mXorState256 apInput, xpState, 0
addq $32, apInput
addq $32, xpState
xorInputToState2:
test $2, aNbrWords
jz xorInputToState1
mXorState128 apInput, xpState, 0
addq $16, apInput
addq $16, xpState
xorInputToState1:
test $1, aNbrWords
jz xorInputToStateDone
movq (apInput), %rax
xorq %rax, (xpState)
xorInputToStateDone:
mPushRegs
mKeccakPermutation
mPopRegs
ret
# -------------------------------------------------------------------------
.size KeccakInitializeState, .-KeccakInitializeState
.align 2
.global KeccakInitializeState
.type KeccakInitializeState, %function
KeccakInitializeState:
xorq %rax, %rax
xorq %rcx, %rcx
notq %rcx
.if UseSIMD == 0
movq %rax, 0*8(apState)
movq %rcx, 1*8(apState)
movq %rcx, 2*8(apState)
movq %rax, 3*8(apState)
movq %rax, 4*8(apState)
movq %rax, 5*8(apState)
movq %rax, 6*8(apState)
movq %rax, 7*8(apState)
movq %rcx, 8*8(apState)
movq %rax, 9*8(apState)
movq %rax, 10*8(apState)
movq %rax, 11*8(apState)
movq %rcx, 12*8(apState)
movq %rax, 13*8(apState)
movq %rax, 14*8(apState)
movq %rax, 15*8(apState)
movq %rax, 16*8(apState)
movq %rcx, 17*8(apState)
movq %rax, 18*8(apState)
movq %rax, 19*8(apState)
movq %rcx, 20*8(apState)
movq %rax, 21*8(apState)
movq %rax, 22*8(apState)
movq %rax, 23*8(apState)
movq %rax, 24*8(apState)
.else
pxor %xmm0, %xmm0
movq %rax, 0*8(apState)
movq %rcx, 1*8(apState)
movq %rcx, 2*8(apState)
movq %rax, 3*8(apState)
movdqu %xmm0, 4*8(apState)
movdqu %xmm0, 6*8(apState)
movq %rcx, 8*8(apState)
movq %rax, 9*8(apState)
movdqu %xmm0, 10*8(apState)
movq %rcx, 12*8(apState)
movq %rax, 13*8(apState)
movdqu %xmm0, 14*8(apState)
movq %rax, 16*8(apState)
movq %rcx, 17*8(apState)
movdqu %xmm0, 18*8(apState)
movq %rcx, 20*8(apState)
movq %rax, 21*8(apState)
movdqu %xmm0, 22*8(apState)
movq %rax, 24*8(apState)
.endif
ret
# -------------------------------------------------------------------------
.size KeccakExtract1024bits, .-KeccakExtract1024bits
.align 2
.global KeccakExtract1024bits
.type KeccakExtract1024bits, %function
KeccakExtract1024bits:
movq 0*8(apState), %rax
movq 1*8(apState), %rcx
movq 2*8(apState), %rdx
movq 3*8(apState), %r8
notq %rcx
notq %rdx
movq %rax, 0*8(%rsi)
movq %rcx, 1*8(%rsi)
movq %rdx, 2*8(%rsi)
movq %r8, 3*8(%rsi)
movq 4*8(apState), %rax
movq 5*8(apState), %rcx
movq 6*8(apState), %rdx
movq 7*8(apState), %r8
movq %rax, 4*8(%rsi)
movq %rcx, 5*8(%rsi)
movq %rdx, 6*8(%rsi)
movq %r8, 7*8(%rsi)
movq 8*8(apState), %rax
movq 9*8(apState), %rcx
movq 10*8(apState), %rdx
movq 11*8(apState), %r8
notq %rax
movq %rax, 8*8(%rsi)
movq %rcx, 9*8(%rsi)
movq %rdx, 10*8(%rsi)
movq %r8, 11*8(%rsi)
movq 12*8(apState), %rax
movq 13*8(apState), %rcx
movq 14*8(apState), %rdx
movq 15*8(apState), %r8
notq %rax
movq %rax, 12*8(%rsi)
movq %rcx, 13*8(%rsi)
movq %rdx, 14*8(%rsi)
movq %r8, 15*8(%rsi)
ret

View File

@ -37,7 +37,7 @@ int InitSponge(spongeState *state, unsigned int rate, unsigned int capacity)
return 0;
}
void AbsorbQueue(spongeState *state)
static void AbsorbQueue(spongeState *state)
{
// state->bitsInQueue is assumed to be equal to state->rate
#ifdef KeccakReference
@ -191,7 +191,7 @@ int Absorb(spongeState *state, const unsigned char *data, unsigned long long dat
return 0;
}
void PadAndSwitchToSqueezingPhase(spongeState *state)
static void PadAndSwitchToSqueezingPhase(spongeState *state)
{
// Note: the bits are numbered from 0=LSB to 7=MSB
if (state->bitsInQueue + 1 == state->rate) {

74
c_src/Makefile Normal file
View File

@ -0,0 +1,74 @@
# Based on c_src.mk from erlang.mk by Loic Hoguin <essen@ninenines.eu>
CURDIR := $(shell pwd)
BASEDIR := $(abspath $(CURDIR)/..)
PROJECT ?= $(notdir $(BASEDIR))
PROJECT := erlang-sha3
ERTS_INCLUDE_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~s/erts-~s/include/\", [code:root_dir(), erlang:system_info(version)]).")
ERL_INTERFACE_INCLUDE_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~s\", [code:lib_dir(erl_interface, include)]).")
ERL_INTERFACE_LIB_DIR ?= $(shell erl -noshell -s init stop -eval "io:format(\"~s\", [code:lib_dir(erl_interface, lib)]).")
C_SRC_DIR = $(CURDIR)
C_SRC_OUTPUT ?= $(CURDIR)/../priv/$(PROJECT).so
# System type and C compiler/flags.
UNAME_SYS := $(shell uname -s)
ifeq ($(UNAME_SYS), Darwin)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -arch x86_64 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -arch x86_64 -finline-functions -Wall
LDFLAGS ?= -arch x86_64 -flat_namespace -undefined suppress
else ifeq ($(UNAME_SYS), FreeBSD)
CC ?= cc
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -finline-functions -Wall
else ifeq ($(UNAME_SYS), Linux)
CC ?= gcc
CFLAGS ?= -O3 -std=c99 -finline-functions -Wall -Wmissing-prototypes
CXXFLAGS ?= -O3 -finline-functions -Wall
endif
CFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
CXXFLAGS += -fPIC -I $(ERTS_INCLUDE_DIR) -I $(ERL_INTERFACE_INCLUDE_DIR)
LDLIBS += -L $(ERL_INTERFACE_LIB_DIR) -lerl_interface -lei
LDFLAGS += -shared
# Verbosity.
c_verbose_0 = @echo " C " $(?F);
c_verbose = $(c_verbose_$(V))
cpp_verbose_0 = @echo " CPP " $(?F);
cpp_verbose = $(cpp_verbose_$(V))
link_verbose_0 = @echo " LD " $(@F);
link_verbose = $(link_verbose_$(V))
SOURCES := $(shell find $(C_SRC_DIR) -type f \( -name "*.c" -o -name "*.C" -o -name "*.cc" -o -name "*.cpp" \))
OBJECTS = $(addsuffix .o, $(basename $(SOURCES)))
COMPILE_C = $(c_verbose) $(CC) $(CFLAGS) $(CPPFLAGS) -c
COMPILE_CPP = $(cpp_verbose) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c
$(C_SRC_OUTPUT): $(OBJECTS)
@mkdir -p $(BASEDIR)/priv/
$(link_verbose) $(CC) $(OBJECTS) $(LDFLAGS) $(LDLIBS) -o $(C_SRC_OUTPUT)
%.o: %.c
$(COMPILE_C) $(OUTPUT_OPTION) $<
%.o: %.cc
$(COMPILE_CPP) $(OUTPUT_OPTION) $<
%.o: %.C
$(COMPILE_CPP) $(OUTPUT_OPTION) $<
%.o: %.cpp
$(COMPILE_CPP) $(OUTPUT_OPTION) $<
clean:
@rm -f $(C_SRC_OUTPUT) $(OBJECTS)

View File

@ -110,7 +110,7 @@ void displayRoundNumber(int level, unsigned int i)
void displayText(int level, const char *text)
{
if ((intermediateValueFile) && (level <= displayLevel)) {
fprintf(intermediateValueFile, text);
fprintf(intermediateValueFile, "%s", text);
fprintf(intermediateValueFile, "\n");
fprintf(intermediateValueFile, "\n");
}

View File

@ -1,7 +1,7 @@
@title SHA-3 for Erlang
@author SUZUKI Tetsuya <tetsuya.suzuki@gmail.com>
@copyright 2012- SUZUKI Tetsuya
@version 0.1.0
@version 0.1.1
@reference <a href="http://en.wikipedia.org/wiki/SHA-3">Wikipedia: SHA-3</a>
@reference <a href="http://csrc.nist.gov/groups/ST/hash/sha-3/index.html">NIST: Cryptographic Hash Algorithm Competition</a>
@reference <a href="http://keccak.noekeon.org/">The Keccak sponge function family</a>

BIN
rebar vendored

Binary file not shown.

View File

@ -1,33 +1,32 @@
{erl_opts, [{i, "src"},
warnings_as_errors,
debug_info,
{w, all},
warn_export_all]}.
{clean_files, [".eunit",
"ebin/*.beam"]}.
{deps, [{hex2bin, "1.0.0"}]}.
{port_env, [{"CFLAGS", "$CFLAGS -O2 -finline-functions -fomit-frame-pointer -fno-strict-aliasing -Wmissing-prototypes -Wall -std=c99"}]}.
{plugins, [pc]}.
{provider_hooks, [
{pre, [
{compile, {pc, compile}},
{clean, {pc, clean}}
]}
]}.
{port_specs, [
% TODO: support optimization
% {"i386", "priv/sha3_nif.so", ["c_src/sha3_nif.c",
% "c_src/KeccakNISTInterface.c",
% "c_src/KeccakSponge.c",
% "c_src/KeccakF-1600-opt32.c",
% "c_src/displayIntermediateValues.c"]},
% {"x86_64", "priv/sha3_nif.so", ["c_src/sha3_nif.c",
% "c_src/KeccakNISTInterface.c",
% "c_src/KeccakSponge.c",
% "c_src/KeccakF-1600-opt64.c",
% "c_src/displayIntermediateValues.c"]},
{"priv/sha3_nif.so", ["c_src/sha3_nif.c",
"c_src/KeccakNISTInterface.c",
"c_src/KeccakSponge.c",
"c_src/KeccakF-1600-reference.c",
"c_src/displayIntermediateValues.c"]}
{"priv/sha3_nif.so", [
"c_src/*.c"
]}
]}.
{port_env, [
{"(linux|darwin)", "CFLAGS", "$CFLAGS -O2 -finline-functions -fomit-frame-pointer -fno-strict-aliasing -Wmissing-prototypes -Wall -std=c99"},
{"win32", "CFLAGS", "$CFLAGS /LD /O2 /DNDEBUG"}
]}.
{eunit_opts, [{report,{eunit_surefire,[{dir,"."}]}}]}.
{xref_checks, [fail_on_warning, undefined_function_calls]}.

6
rebar.lock Normal file
View File

@ -0,0 +1,6 @@
{"1.1.0",
[{<<"hex2bin">>,{pkg,<<"hex2bin">>,<<"1.0.0">>},0}]}.
[
{pkg_hash,[
{<<"hex2bin">>, <<"AAC26EAB998AE80EACEE1C7607C629AB503EBF77A62B9242BAE2B94D47DCB71E">>}]}
].

BIN
rebar3 Executable file

Binary file not shown.

View File

@ -1,11 +1,12 @@
{application, sha3,
[
{description, ""},
{vsn, "0.1.0"},
{description, "SHA-3 and Keccak in NIF and native Erlang."},
{vsn, "0.1.5"},
{registered, []},
{applications, [
kernel,
stdlib
stdlib,
hex2bin
]},
{modules, [sha3]},
{env, []}

View File

@ -1,41 +1,613 @@
-module(sha3).
%%% @doc
%%% 2023-02-14: Update - Craig Everett
%%% Adapting native Erlang Keccak implementation as a NIF fallback
%%% to increase portability. Native Keccak implementation provided
%%% courtesy of Peter Harpending and Hans Svensson.
%%%
%%% Kek repo:
%%% https://github.com/pharpend/kek
%%%
%%% Peter Harpending: https://github.com/pharpend https://git.qpq.swiss/pharpend
%%% Hans Svensson: https://github.com/hanssv https://git.qpq.swiss/hanssv
%%% Craig Everett: https://gitlab.com/zxq9 https://git.qpq.swiss/zxq9
-module(sha3).
-vsn("0.1.5").
-export([hash_init/1, hash_update/2, hash_final/1, hash/2, kek/2, kek/3, shake128/2, shake256/2]).
-export([hash_init/1, hash_update/2, hash_final/1, hash/2]).
-on_load(init/0).
-type bitlen() :: 224 | 256 | 384 | 512.
-type context() :: binary().
%% State of hash operation return.
-type digest() :: <<_:224>> | <<_:256>> | <<_:384>> | <<_:512>>.
-export_type([bitlen/0, context/0, digest/0]).
-define(nif_stub, nif_stub_error(?LINE)).
nif_stub_error(Line) ->
erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).
erlang:nif_error({nif_not_loaded, module, ?MODULE, line, Line}).
init() ->
PrivDir = case code:priv_dir(?MODULE) of
{error, bad_name} ->
EbinDir = filename:dirname(code:which(?MODULE)),
AppPath = filename:dirname(EbinDir),
filename:join(AppPath, "priv");
Path ->
Path
end,
erlang:load_nif(filename:join(PrivDir, sha3_nif), 0).
PrivDir =
case code:priv_dir(?MODULE) of
{error, bad_name} ->
EbinDir = filename:dirname(code:which(?MODULE)),
AppPath = filename:dirname(EbinDir),
filename:join(AppPath, "priv");
Path ->
Path
end,
case erlang:load_nif(filename:join(PrivDir, sha3_nif), 0) of
ok ->
logger:info("erlang-sha3 NIF loaded.");
{error, {Reason, Message}} ->
Format =
"erlang-sha3 NIF failed to load with ~tw: ~ts. "
"Falling back to Erlang implementation.",
logger:info(Format, [Reason, Message])
end.
-spec hash_init(bitlen()) -> context().
%% @doc Returns a new context for hash operation.
%% Bit length of digest (`BitLen') must be one of 224, 256, 384 and 512.
%% @see hash_update/2
hash_init(_BitLen) ->
?nif_stub.
-spec hash_update(context(), binary()) -> context().
%% @doc Updates the digest by `Context' generated with `hash_init/1'
%% using the given `Data' and returns a new updated context.
%% `Data' can be any length.
%% The returned context can e used `hash_update/2' or `hash_final/1'.
%% @see hash_final/1
hash_update(_Context, _Binary) ->
?nif_stub.
-spec hash_final(context()) -> digest().
%% @doc Finalizes the hash operation with `Context' and
%% returns a message digest.
%% Length of the digest is determined by an argument of `hash_init/1'.
hash_final(_Context) ->
?nif_stub.
-spec hash(bitlen(), binary()) -> digest().
hash(_BitLen, _Binary) ->
?nif_stub.
-spec hash(OutputBitLength, Message) -> Digest
when OutputBitLength :: pos_integer(),
Message :: bitstring(),
Digest :: bitstring().
%% @doc
%% SHA-3 with an arbitrary output bit length.
%%
%% This means Keccak with Capacity = 2 * OutputBitLength. Additionally, SHA3
%% concatenates the bits 01 onto the end of the input, before sending the
%% Message to keccak/3.
%% @end
hash(224, Message) -> kek(224, Message);
hash(256, Message) -> kek(256, Message);
hash(384, Message) -> kek(382, Message);
hash(512, Message) -> kek(512, Message);
hash(_, _) -> error(badarg).
kek(Length, Message) ->
kek(Length, Message, keccak).
kek(OutputBitLength, Message, keccak) ->
Capacity = 2 * OutputBitLength,
keccak(Capacity, Message, <<>>, OutputBitLength);
kek(OutputBitLength, Message, nist) ->
Capacity = 2 * OutputBitLength,
keccak(Capacity, Message, <<2#01:2>>, OutputBitLength).
-spec shake128(Message, OutputBitLength) -> Digest
when Message :: bitstring(),
OutputBitLength :: pos_integer(),
Digest :: bitstring().
%% @doc
%% This is the SHAKE variable-length hash with Capacity 256 = 2*128 bits.
%% @end
shake128(Message, OutputBitLength) ->
shake(128, Message, OutputBitLength).
-spec shake256(Message, OutputBitLength) -> Digest
when Message :: bitstring(),
OutputBitLength :: pos_integer(),
Digest :: bitstring().
%% @doc
%% This is the SHAKE variable-length hash with Capacity 512 = 2*256 bits.
%% @end
shake256(Message, OutputBitLength) ->
shake(256, Message, OutputBitLength).
-spec shake(ShakeNumber, Message, OutputBitLength) -> Digest
when ShakeNumber :: pos_integer(),
Message :: bitstring(),
OutputBitLength :: pos_integer(),
Digest :: bitstring().
%% @doc
%% This is the SHAKE variable-length hash with Capacity 512 = 2*ShakeNumber bits.
%%
%% This concatenates the bitstring 1111 onto the end of the Message before
%% sending the message to keccak/4.
%% @end
shake(ShakeNumber, Message, OutputBitLength) ->
Capacity = 2 * ShakeNumber,
keccak(Capacity, Message, <<2#1111:4>>, OutputBitLength).
%%% OUTER KECCAK
%%%
%%% Keccak pads the input, absorbs it into the sponge, and squeezes the bits out
%%% of the sponge. The absorption and squeezing phases invoke "inner keccak",
%%% which is the heart of the algorithm.
%%%
%%% - keccak/3
%%% - pad/2
%%% - absorb/4
%%% - squeeze/3
-spec keccak(Capacity, Message, Delimiter, OutputBitLength) -> Digest
when Capacity :: pos_integer(),
Message :: bitstring(),
Delimiter :: bitstring(),
OutputBitLength :: pos_integer(),
Digest :: bitstring().
%% @doc
%% Note: this is Keccak 1600, the only one used in practice
%%
%% Capacity must be strictly less than 1600
%% @end
keccak(Capacity, Message, Delimiter, OutputBitLength) ->
BitRate = 1600 - Capacity,
PaddedMessage = pad(Message, Delimiter, BitRate),
InitialSponge = <<0:1600>>,
WetSponge = absorb(PaddedMessage, BitRate, Capacity, InitialSponge),
ResultBits = squeeze(WetSponge, OutputBitLength, BitRate),
ResultBits.
-spec pad(Message, Delimiter, BitRate) -> NewMessage
when Message :: bitstring(),
Delimiter :: bitstring(),
BitRate :: pos_integer(),
NewMessage :: bitstring().
%% @private
%% padding
%% divide the message into r-bit blocks
%%
%% the message ends with 1000...0001
%%
%% sha3 calls this /10*1/ as in the regex
%%
%% Reference: https://en.wikipedia.org/wiki/SHA-3#Padding
%% @end
pad(Msg, Delimiter, BitRate) ->
MsgBits = bit_size(Msg),
DlmBits = bit_size(Delimiter),
<<Msg0:(MsgBits div 8)/bytes, Msg1/bitstring>> = Msg,
case (MsgBits + DlmBits) rem BitRate of
0 -> %% We add a complete RWord + flip the last chunk of the message
<<Msg0/binary, (rev_pad(Msg1, Delimiter, BitRate - 2))/bitstring>>;
N when N == BitRate - 1 -> %% Slightly retarded case
<<Msg0/binary, (rev_pad(Msg1, Delimiter, BitRate - 1))/bitstring>>;
N ->
<<Msg0/binary, (rev_pad(Msg1, Delimiter, BitRate - N - 2))/bitstring>>
end.
%% Instead of reverting message bits, work with a "reversed" padding
rev_pad(Msg, Delimiter, PadZeros) ->
Pad = <<Msg/bitstring, Delimiter/bitstring, 1:1, 0:PadZeros, 1:1>>,
<< (flip_bits(X)) || <<X:8>> <= Pad >>.
flip_bits(0) -> <<0:8>>;
flip_bits(<<A:1, B:1, C:1, D:1, E:1, F:1, G:1, H:1>>) ->
<<H:1, G:1, F:1, E:1, D:1, C:1, B:1, A:1>>;
flip_bits(N) -> flip_bits(<<N:8>>).
-spec absorb(PaddedMessage, BitRate, Capacity, SpongeAcc) -> WetSponge
when PaddedMessage :: bitstring(),
BitRate :: pos_integer(),
Capacity :: pos_integer(),
SpongeAcc :: <<_:1600>>,
WetSponge :: <<_:1600>>.
%% @private
%% Assumptions:
%% 1. BitRate + Capacity = 1600,
%% 2. BitRate divides the PaddedMessage length (i.e. already have done padding)
%% @end
% can pull off r bits from the start of the message
absorb(PaddedMessageBits, BitRate = _r, Capacity = _c, Sponge) when BitRate =< bit_size(PaddedMessageBits) ->
<<ThisRWord:BitRate, Rest/bitstring>> = PaddedMessageBits,
% we bitwise xor the sponge against the r word followed by a bunch of 0s
<<SpongeInt:1600>> = Sponge,
<<Foo:1600>> = <<ThisRWord:BitRate, 0:Capacity>>,
FInputInt = SpongeInt bxor Foo,
FInputBits = <<FInputInt:1600>>,
NewSponge = inner_keccak(FInputBits),
absorb(Rest, BitRate, Capacity, NewSponge);
% empty string, return the sponge
absorb(<<>>, _r, _c, FinalSponge) ->
FinalSponge.
-spec squeeze(WetSponge, OutputBitLength, BitRate) -> ResultBits
when WetSponge :: <<_:1600>>,
OutputBitLength :: pos_integer(),
BitRate :: pos_integer(),
ResultBits :: bitstring().
%% @private
%% squeeze the output bits out of the sponge
%% @end
%%% % simple case: bit length is less than (or equal to) the sponge size, just grab
%%% % the first ones
%%% % this is the case for the shas
%%% squeeze(<<ResultBits:OutputBitLength, _Rest/bitstring>>, OutputBitLength, _BitRate) ->
%%% <<ResultBits:OutputBitLength>>;
% general case: output bit length is greater than the sponge size, construct
% accumulatively
% this is the case for the variable-length encodings
squeeze(WetSponge, OutputBitLength, BitRate) ->
InitOutputAcc = <<>>,
really_squeeze(WetSponge, OutputBitLength, BitRate, InitOutputAcc).
% terminal case: we have enough bits in the output, return those
really_squeeze(_WetSponge, OutputBitLength, _BitRate, FinalAccBits) when OutputBitLength =< bit_size(FinalAccBits) ->
<<ResultBits:OutputBitLength, _/bitstring>> = FinalAccBits,
<<ResultBits:OutputBitLength>>;
% general case: need moar bits
% in this case
% - we grab the first r bits of the sponge, add them to the accumulator
% - re-kek the sponge
% - try again
really_squeeze(WetSponge, OutputBitLength, BitRate, ResultAcc)->
<<ThisRWord:BitRate, _/bitstring>> = WetSponge,
NewResultAcc = <<ResultAcc/bitstring, ThisRWord:BitRate>>,
NewWetSponge = inner_keccak(WetSponge),
really_squeeze(NewWetSponge, OutputBitLength, BitRate, NewResultAcc).
%%% THE DREADED INNER KECCAK
%%%
%%% This is the "f" function that appears in all the documentation.
%%%
%%% The input is the 1600-bit sponge array. inner_keccak/1 sends the input
%%% through 24 "rounds". Each round consists of the 5 Greek letter steps, each of
%%% which is a weird transformation on the array.
%%%
%%% Here the rounds are unrolled in terms of 64bit integers - for efficiency
inner_keccak(<<_:1600>> = State) ->
IntState0 = list_to_tuple([ X || <<X:64/little>> <= State ]),
IntState6 = inner_keccak_fast(IntState0),
<< <<X:64/little>> || X <- tuple_to_list(IntState6) >>.
inner_keccak_fast(IntState0) ->
IntState1 = fast_round(IntState0, {16#0000000000000001, 16#0000000000008082, 16#800000000000808A, 16#8000000080008000}),
IntState2 = fast_round(IntState1, {16#000000000000808B, 16#0000000080000001, 16#8000000080008081, 16#8000000000008009}),
IntState3 = fast_round(IntState2, {16#000000000000008A, 16#0000000000000088, 16#0000000080008009, 16#000000008000000A}),
IntState4 = fast_round(IntState3, {16#000000008000808B, 16#800000000000008B, 16#8000000000008089, 16#8000000000008003}),
IntState5 = fast_round(IntState4, {16#8000000000008002, 16#8000000000000080, 16#000000000000800A, 16#800000008000000A}),
fast_round(IntState5, {16#8000000080008081, 16#8000000000008080, 16#0000000080000001, 16#8000000080008008}).
-define(INT64, 16#FFFFFFFFFFFFFFFF).
-define(BSL64(X, N), ((X bsl N) band ?INT64)).
-define(BSR64(X, N), (X bsr N)).
-define(ROTL64(X, N), (?BSL64(X, N) bor ?BSR64(X, (64 - N)))).
-define(CAN64(A, B), ((A bxor B) band A)).
fast_round(As0, {RC0, RC1, RC2, RC3}) ->
As1 = fast_round1(As0, RC0),
As2 = fast_round2(As1, RC1),
As3 = fast_round3(As2, RC2),
fast_round4(As3, RC3).
fast_round1({A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24}, RC0) ->
%% Round 1
BC0_0 = A0 bxor A5 bxor A10 bxor A15 bxor A20,
BC1_0 = A1 bxor A6 bxor A11 bxor A16 bxor A21,
BC2_0 = A2 bxor A7 bxor A12 bxor A17 bxor A22,
BC3_0 = A3 bxor A8 bxor A13 bxor A18 bxor A23,
BC4_0 = A4 bxor A9 bxor A14 bxor A19 bxor A24,
D0 = BC4_0 bxor ?ROTL64(BC1_0, 1),
D1 = BC0_0 bxor ?ROTL64(BC2_0, 1),
D2 = BC1_0 bxor ?ROTL64(BC3_0, 1),
D3 = BC2_0 bxor ?ROTL64(BC4_0, 1),
D4 = BC3_0 bxor ?ROTL64(BC0_0, 1),
BC0_1 = A0 bxor D0,
BC1_1 = ?ROTL64(A6 bxor D1, 44),
BC2_1 = ?ROTL64(A12 bxor D2, 43),
BC3_1 = ?ROTL64(A18 bxor D3, 21),
BC4_1 = ?ROTL64(A24 bxor D4, 14),
A0_1 = BC0_1 bxor ?CAN64(BC2_1, BC1_1) bxor RC0,
A6_1 = BC1_1 bxor ?CAN64(BC3_1, BC2_1),
A12_1 = BC2_1 bxor ?CAN64(BC4_1, BC3_1),
A18_1 = BC3_1 bxor ?CAN64(BC0_1, BC4_1),
A24_1 = BC4_1 bxor ?CAN64(BC1_1, BC0_1),
BC2_2 = ?ROTL64(A10 bxor D0, 3),
BC3_2 = ?ROTL64(A16 bxor D1, 45),
BC4_2 = ?ROTL64(A22 bxor D2, 61),
BC0_2 = ?ROTL64(A3 bxor D3, 28),
BC1_2 = ?ROTL64(A9 bxor D4, 20),
A10_1 = BC0_2 bxor ?CAN64(BC2_2, BC1_2),
A16_1 = BC1_2 bxor ?CAN64(BC3_2, BC2_2),
A22_1 = BC2_2 bxor ?CAN64(BC4_2, BC3_2),
A3_1 = BC3_2 bxor ?CAN64(BC0_2, BC4_2),
A9_1 = BC4_2 bxor ?CAN64(BC1_2, BC0_2),
BC4_3 = ?ROTL64(A20 bxor D0, 18),
BC0_3 = ?ROTL64(A1 bxor D1, 1),
BC1_3 = ?ROTL64(A7 bxor D2, 6),
BC2_3 = ?ROTL64(A13 bxor D3, 25),
BC3_3 = ?ROTL64(A19 bxor D4, 8),
A20_1 = BC0_3 bxor ?CAN64(BC2_3, BC1_3),
A1_1 = BC1_3 bxor ?CAN64(BC3_3, BC2_3),
A7_1 = BC2_3 bxor ?CAN64(BC4_3, BC3_3),
A13_1 = BC3_3 bxor ?CAN64(BC0_3, BC4_3),
A19_1 = BC4_3 bxor ?CAN64(BC1_3, BC0_3),
BC1_4 = ?ROTL64(A5 bxor D0, 36),
BC2_4 = ?ROTL64(A11 bxor D1, 10),
BC3_4 = ?ROTL64(A17 bxor D2, 15),
BC4_4 = ?ROTL64(A23 bxor D3, 56),
BC0_4 = ?ROTL64(A4 bxor D4, 27),
A5_1 = BC0_4 bxor ?CAN64(BC2_4, BC1_4),
A11_1 = BC1_4 bxor ?CAN64(BC3_4, BC2_4),
A17_1 = BC2_4 bxor ?CAN64(BC4_4, BC3_4),
A23_1 = BC3_4 bxor ?CAN64(BC0_4, BC4_4),
A4_1 = BC4_4 bxor ?CAN64(BC1_4, BC0_4),
BC3_5 = ?ROTL64(A15 bxor D0, 41),
BC4_5 = ?ROTL64(A21 bxor D1, 2),
BC0_5 = ?ROTL64(A2 bxor D2, 62),
BC1_5 = ?ROTL64(A8 bxor D3, 55),
BC2_5 = ?ROTL64(A14 bxor D4, 39),
A15_1 = BC0_5 bxor ?CAN64(BC2_5, BC1_5),
A21_1 = BC1_5 bxor ?CAN64(BC3_5, BC2_5),
A2_1 = BC2_5 bxor ?CAN64(BC4_5, BC3_5),
A8_1 = BC3_5 bxor ?CAN64(BC0_5, BC4_5),
A14_1 = BC4_5 bxor ?CAN64(BC1_5, BC0_5),
{A0_1, A1_1, A2_1, A3_1, A4_1, A5_1, A6_1, A7_1, A8_1, A9_1, A10_1, A11_1, A12_1, A13_1,
A14_1, A15_1, A16_1, A17_1, A18_1, A19_1, A20_1, A21_1, A22_1, A23_1, A24_1}.
fast_round2({A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24}, RC1) ->
%% Round 2
BC0_0 = A0 bxor A5 bxor A10 bxor A15 bxor A20,
BC1_0 = A1 bxor A6 bxor A11 bxor A16 bxor A21,
BC2_0 = A2 bxor A7 bxor A12 bxor A17 bxor A22,
BC3_0 = A3 bxor A8 bxor A13 bxor A18 bxor A23,
BC4_0 = A4 bxor A9 bxor A14 bxor A19 bxor A24,
D0 = BC4_0 bxor ?ROTL64(BC1_0, 1),
D1 = BC0_0 bxor ?ROTL64(BC2_0, 1),
D2 = BC1_0 bxor ?ROTL64(BC3_0, 1),
D3 = BC2_0 bxor ?ROTL64(BC4_0, 1),
D4 = BC3_0 bxor ?ROTL64(BC0_0, 1),
BC0_1 = A0 bxor D0,
BC1_1 = ?ROTL64(A16 bxor D1, 44),
BC2_1 = ?ROTL64(A7 bxor D2, 43),
BC3_1 = ?ROTL64(A23 bxor D3, 21),
BC4_1 = ?ROTL64(A14 bxor D4, 14),
A0_1 = BC0_1 bxor ?CAN64(BC2_1, BC1_1) bxor RC1,
A16_1 = BC1_1 bxor ?CAN64(BC3_1, BC2_1),
A7_1 = BC2_1 bxor ?CAN64(BC4_1, BC3_1),
A23_1 = BC3_1 bxor ?CAN64(BC0_1, BC4_1),
A14_1 = BC4_1 bxor ?CAN64(BC1_1, BC0_1),
BC2_2 = ?ROTL64(A20 bxor D0, 3),
BC3_2 = ?ROTL64(A11 bxor D1, 45),
BC4_2 = ?ROTL64(A2 bxor D2, 61),
BC0_2 = ?ROTL64(A18 bxor D3, 28),
BC1_2 = ?ROTL64(A9 bxor D4, 20),
A20_1 = BC0_2 bxor ?CAN64(BC2_2, BC1_2),
A11_1 = BC1_2 bxor ?CAN64(BC3_2, BC2_2),
A2_1 = BC2_2 bxor ?CAN64(BC4_2, BC3_2),
A18_1 = BC3_2 bxor ?CAN64(BC0_2, BC4_2),
A9_1 = BC4_2 bxor ?CAN64(BC1_2, BC0_2),
BC4_3 = ?ROTL64(A15 bxor D0, 18),
BC0_3 = ?ROTL64(A6 bxor D1, 1),
BC1_3 = ?ROTL64(A22 bxor D2, 6),
BC2_3 = ?ROTL64(A13 bxor D3, 25),
BC3_3 = ?ROTL64(A4 bxor D4, 8),
A15_1 = BC0_3 bxor ?CAN64(BC2_3, BC1_3),
A6_1 = BC1_3 bxor ?CAN64(BC3_3, BC2_3),
A22_1 = BC2_3 bxor ?CAN64(BC4_3, BC3_3),
A13_1 = BC3_3 bxor ?CAN64(BC0_3, BC4_3),
A4_1 = BC4_3 bxor ?CAN64(BC1_3, BC0_3),
BC1_4 = ?ROTL64(A10 bxor D0, 36),
BC2_4 = ?ROTL64(A1 bxor D1, 10),
BC3_4 = ?ROTL64(A17 bxor D2, 15),
BC4_4 = ?ROTL64(A8 bxor D3, 56),
BC0_4 = ?ROTL64(A24 bxor D4, 27),
A10_1 = BC0_4 bxor ?CAN64(BC2_4, BC1_4),
A1_1 = BC1_4 bxor ?CAN64(BC3_4, BC2_4),
A17_1 = BC2_4 bxor ?CAN64(BC4_4, BC3_4),
A8_1 = BC3_4 bxor ?CAN64(BC0_4, BC4_4),
A24_1 = BC4_4 bxor ?CAN64(BC1_4, BC0_4),
BC3_5 = ?ROTL64(A5 bxor D0, 41),
BC4_5 = ?ROTL64(A21 bxor D1, 2),
BC0_5 = ?ROTL64(A12 bxor D2, 62),
BC1_5 = ?ROTL64(A3 bxor D3, 55),
BC2_5 = ?ROTL64(A19 bxor D4, 39),
A5_1 = BC0_5 bxor ?CAN64(BC2_5, BC1_5),
A21_1 = BC1_5 bxor ?CAN64(BC3_5, BC2_5),
A12_1 = BC2_5 bxor ?CAN64(BC4_5, BC3_5),
A3_1 = BC3_5 bxor ?CAN64(BC0_5, BC4_5),
A19_1 = BC4_5 bxor ?CAN64(BC1_5, BC0_5),
{A0_1, A1_1, A2_1, A3_1, A4_1, A5_1, A6_1, A7_1, A8_1, A9_1, A10_1, A11_1, A12_1, A13_1,
A14_1, A15_1, A16_1, A17_1, A18_1, A19_1, A20_1, A21_1, A22_1, A23_1, A24_1}.
fast_round3({A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24}, RC2) ->
%% Round 3
BC0_0 = A0 bxor A5 bxor A10 bxor A15 bxor A20,
BC1_0 = A1 bxor A6 bxor A11 bxor A16 bxor A21,
BC2_0 = A2 bxor A7 bxor A12 bxor A17 bxor A22,
BC3_0 = A3 bxor A8 bxor A13 bxor A18 bxor A23,
BC4_0 = A4 bxor A9 bxor A14 bxor A19 bxor A24,
D0 = BC4_0 bxor ?ROTL64(BC1_0, 1),
D1 = BC0_0 bxor ?ROTL64(BC2_0, 1),
D2 = BC1_0 bxor ?ROTL64(BC3_0, 1),
D3 = BC2_0 bxor ?ROTL64(BC4_0, 1),
D4 = BC3_0 bxor ?ROTL64(BC0_0, 1),
BC0_1 = A0 bxor D0,
BC1_1 = ?ROTL64(A11 bxor D1, 44),
BC2_1 = ?ROTL64(A22 bxor D2, 43),
BC3_1 = ?ROTL64(A8 bxor D3, 21),
BC4_1 = ?ROTL64(A19 bxor D4, 14),
A0_1 = BC0_1 bxor ?CAN64(BC2_1, BC1_1) bxor RC2,
A11_1 = BC1_1 bxor ?CAN64(BC3_1, BC2_1),
A22_1 = BC2_1 bxor ?CAN64(BC4_1, BC3_1),
A8_1 = BC3_1 bxor ?CAN64(BC0_1, BC4_1),
A19_1 = BC4_1 bxor ?CAN64(BC1_1, BC0_1),
BC2_2 = ?ROTL64(A15 bxor D0, 3),
BC3_2 = ?ROTL64(A1 bxor D1, 45),
BC4_2 = ?ROTL64(A12 bxor D2, 61),
BC0_2 = ?ROTL64(A23 bxor D3, 28),
BC1_2 = ?ROTL64(A9 bxor D4, 20),
A15_1 = BC0_2 bxor ?CAN64(BC2_2, BC1_2),
A1_1 = BC1_2 bxor ?CAN64(BC3_2, BC2_2),
A12_1 = BC2_2 bxor ?CAN64(BC4_2, BC3_2),
A23_1 = BC3_2 bxor ?CAN64(BC0_2, BC4_2),
A9_1 = BC4_2 bxor ?CAN64(BC1_2, BC0_2),
BC4_3 = ?ROTL64(A5 bxor D0, 18),
BC0_3 = ?ROTL64(A16 bxor D1, 1),
BC1_3 = ?ROTL64(A2 bxor D2, 6),
BC2_3 = ?ROTL64(A13 bxor D3, 25),
BC3_3 = ?ROTL64(A24 bxor D4, 8),
A5_1 = BC0_3 bxor ?CAN64(BC2_3, BC1_3),
A16_1 = BC1_3 bxor ?CAN64(BC3_3, BC2_3),
A2_1 = BC2_3 bxor ?CAN64(BC4_3, BC3_3),
A13_1 = BC3_3 bxor ?CAN64(BC0_3, BC4_3),
A24_1 = BC4_3 bxor ?CAN64(BC1_3, BC0_3),
BC1_4 = ?ROTL64(A20 bxor D0, 36),
BC2_4 = ?ROTL64(A6 bxor D1, 10),
BC3_4 = ?ROTL64(A17 bxor D2, 15),
BC4_4 = ?ROTL64(A3 bxor D3, 56),
BC0_4 = ?ROTL64(A14 bxor D4, 27),
A20_1 = BC0_4 bxor ?CAN64(BC2_4, BC1_4),
A6_1 = BC1_4 bxor ?CAN64(BC3_4, BC2_4),
A17_1 = BC2_4 bxor ?CAN64(BC4_4, BC3_4),
A3_1 = BC3_4 bxor ?CAN64(BC0_4, BC4_4),
A14_1 = BC4_4 bxor ?CAN64(BC1_4, BC0_4),
BC3_5 = ?ROTL64(A10 bxor D0, 41),
BC4_5 = ?ROTL64(A21 bxor D1, 2),
BC0_5 = ?ROTL64(A7 bxor D2, 62),
BC1_5 = ?ROTL64(A18 bxor D3, 55),
BC2_5 = ?ROTL64(A4 bxor D4, 39),
A10_1 = BC0_5 bxor ?CAN64(BC2_5, BC1_5),
A21_1 = BC1_5 bxor ?CAN64(BC3_5, BC2_5),
A7_1 = BC2_5 bxor ?CAN64(BC4_5, BC3_5),
A18_1 = BC3_5 bxor ?CAN64(BC0_5, BC4_5),
A4_1 = BC4_5 bxor ?CAN64(BC1_5, BC0_5),
{A0_1, A1_1, A2_1, A3_1, A4_1, A5_1, A6_1, A7_1, A8_1, A9_1, A10_1, A11_1, A12_1, A13_1,
A14_1, A15_1, A16_1, A17_1, A18_1, A19_1, A20_1, A21_1, A22_1, A23_1, A24_1}.
fast_round4({A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21, A22, A23, A24}, RC3) ->
%% Round 4
BC0_0 = A0 bxor A5 bxor A10 bxor A15 bxor A20,
BC1_0 = A1 bxor A6 bxor A11 bxor A16 bxor A21,
BC2_0 = A2 bxor A7 bxor A12 bxor A17 bxor A22,
BC3_0 = A3 bxor A8 bxor A13 bxor A18 bxor A23,
BC4_0 = A4 bxor A9 bxor A14 bxor A19 bxor A24,
D0 = BC4_0 bxor ?ROTL64(BC1_0, 1),
D1 = BC0_0 bxor ?ROTL64(BC2_0, 1),
D2 = BC1_0 bxor ?ROTL64(BC3_0, 1),
D3 = BC2_0 bxor ?ROTL64(BC4_0, 1),
D4 = BC3_0 bxor ?ROTL64(BC0_0, 1),
BC0_1 = A0 bxor D0,
BC1_1 = ?ROTL64(A1 bxor D1, 44),
BC2_1 = ?ROTL64(A2 bxor D2, 43),
BC3_1 = ?ROTL64(A3 bxor D3, 21),
BC4_1 = ?ROTL64(A4 bxor D4, 14),
A0_1 = BC0_1 bxor ?CAN64(BC2_1, BC1_1) bxor RC3,
A1_1 = BC1_1 bxor ?CAN64(BC3_1, BC2_1),
A2_1 = BC2_1 bxor ?CAN64(BC4_1, BC3_1),
A3_1 = BC3_1 bxor ?CAN64(BC0_1, BC4_1),
A4_1 = BC4_1 bxor ?CAN64(BC1_1, BC0_1),
BC2_2 = ?ROTL64(A5 bxor D0, 3),
BC3_2 = ?ROTL64(A6 bxor D1, 45),
BC4_2 = ?ROTL64(A7 bxor D2, 61),
BC0_2 = ?ROTL64(A8 bxor D3, 28),
BC1_2 = ?ROTL64(A9 bxor D4, 20),
A5_1 = BC0_2 bxor ?CAN64(BC2_2, BC1_2),
A6_1 = BC1_2 bxor ?CAN64(BC3_2, BC2_2),
A7_1 = BC2_2 bxor ?CAN64(BC4_2, BC3_2),
A8_1 = BC3_2 bxor ?CAN64(BC0_2, BC4_2),
A9_1 = BC4_2 bxor ?CAN64(BC1_2, BC0_2),
BC4_3 = ?ROTL64(A10 bxor D0, 18),
BC0_3 = ?ROTL64(A11 bxor D1, 1),
BC1_3 = ?ROTL64(A12 bxor D2, 6),
BC2_3 = ?ROTL64(A13 bxor D3, 25),
BC3_3 = ?ROTL64(A14 bxor D4, 8),
A10_1 = BC0_3 bxor ?CAN64(BC2_3, BC1_3),
A11_1 = BC1_3 bxor ?CAN64(BC3_3, BC2_3),
A12_1 = BC2_3 bxor ?CAN64(BC4_3, BC3_3),
A13_1 = BC3_3 bxor ?CAN64(BC0_3, BC4_3),
A14_1 = BC4_3 bxor ?CAN64(BC1_3, BC0_3),
BC1_4 = ?ROTL64(A15 bxor D0, 36),
BC2_4 = ?ROTL64(A16 bxor D1, 10),
BC3_4 = ?ROTL64(A17 bxor D2, 15),
BC4_4 = ?ROTL64(A18 bxor D3, 56),
BC0_4 = ?ROTL64(A19 bxor D4, 27),
A15_1 = BC0_4 bxor ?CAN64(BC2_4, BC1_4),
A16_1 = BC1_4 bxor ?CAN64(BC3_4, BC2_4),
A17_1 = BC2_4 bxor ?CAN64(BC4_4, BC3_4),
A18_1 = BC3_4 bxor ?CAN64(BC0_4, BC4_4),
A19_1 = BC4_4 bxor ?CAN64(BC1_4, BC0_4),
BC3_5 = ?ROTL64(A20 bxor D0, 41),
BC4_5 = ?ROTL64(A21 bxor D1, 2),
BC0_5 = ?ROTL64(A22 bxor D2, 62),
BC1_5 = ?ROTL64(A23 bxor D3, 55),
BC2_5 = ?ROTL64(A24 bxor D4, 39),
A20_1 = BC0_5 bxor ?CAN64(BC2_5, BC1_5),
A21_1 = BC1_5 bxor ?CAN64(BC3_5, BC2_5),
A22_1 = BC2_5 bxor ?CAN64(BC4_5, BC3_5),
A23_1 = BC3_5 bxor ?CAN64(BC0_5, BC4_5),
A24_1 = BC4_5 bxor ?CAN64(BC1_5, BC0_5),
{A0_1, A1_1, A2_1, A3_1, A4_1, A5_1, A6_1, A7_1, A8_1, A9_1, A10_1, A11_1, A12_1, A13_1,
A14_1, A15_1, A16_1, A17_1, A18_1, A19_1, A20_1, A21_1, A22_1, A23_1, A24_1}.

102
src/sha3.py Normal file
View File

@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
# Implementation by Gilles Van Assche, hereby denoted as "the implementer".
#
# For more information, feedback or questions, please refer to our website:
# https://keccak.team/
#
# To the extent possible under law, the implementer has waived all copyright
# and related or neighboring rights to the source code in this file.
# http://creativecommons.org/publicdomain/zero/1.0/
def ROL64(a, n):
return ((a >> (64-(n%64))) + (a << (n%64))) % (1 << 64)
def KeccakF1600onLanes(lanes):
R = 1
for round in range(24):
# θ
C = [lanes[x][0] ^ lanes[x][1] ^ lanes[x][2] ^ lanes[x][3] ^ lanes[x][4] for x in range(5)]
D = [C[(x+4)%5] ^ ROL64(C[(x+1)%5], 1) for x in range(5)]
lanes = [[lanes[x][y]^D[x] for y in range(5)] for x in range(5)]
# ρ and π
(x, y) = (1, 0)
current = lanes[x][y]
for t in range(24):
(x, y) = (y, (2*x+3*y)%5)
(current, lanes[x][y]) = (lanes[x][y], ROL64(current, (t+1)*(t+2)//2))
# χ
for y in range(5):
T = [lanes[x][y] for x in range(5)]
for x in range(5):
lanes[x][y] = T[x] ^((~T[(x+1)%5]) & T[(x+2)%5])
# ι
for j in range(7):
R = ((R << 1) ^ ((R >> 7)*0x71)) % 256
if (R & 2):
lanes[0][0] = lanes[0][0] ^ (1 << ((1<<j)-1))
return lanes
def load64(b):
return sum((b[i] << (8*i)) for i in range(8))
def store64(a):
return list((a >> (8*i)) % 256 for i in range(8))
def KeccakF1600(state):
lanes = [[load64(state[8*(x+5*y):8*(x+5*y)+8]) for y in range(5)] for x in range(5)]
lanes = KeccakF1600onLanes(lanes)
state = bytearray(200)
for x in range(5):
for y in range(5):
state[8*(x+5*y):8*(x+5*y)+8] = store64(lanes[x][y])
return state
def Keccak(rate, capacity, inputBytes, delimitedSuffix, outputByteLen):
outputBytes = bytearray()
state = bytearray([0 for i in range(200)])
rateInBytes = rate//8
blockSize = 0
if (((rate + capacity) != 1600) or ((rate % 8) != 0)):
return
inputOffset = 0
# === Absorb all the input blocks ===
while(inputOffset < len(inputBytes)):
blockSize = min(len(inputBytes)-inputOffset, rateInBytes)
for i in range(blockSize):
state[i] = state[i] ^ inputBytes[i+inputOffset]
inputOffset = inputOffset + blockSize
if (blockSize == rateInBytes):
state = KeccakF1600(state)
blockSize = 0
# === Do the padding and switch to the squeezing phase ===
state[blockSize] = state[blockSize] ^ delimitedSuffix
if (((delimitedSuffix & 0x80) != 0) and (blockSize == (rateInBytes-1))):
state = KeccakF1600(state)
state[rateInBytes-1] = state[rateInBytes-1] ^ 0x80
state = KeccakF1600(state)
# === Squeeze out all the output blocks ===
while(outputByteLen > 0):
blockSize = min(outputByteLen, rateInBytes)
outputBytes = outputBytes + state[0:blockSize]
outputByteLen = outputByteLen - blockSize
if (outputByteLen > 0):
state = KeccakF1600(state)
return outputBytes
def SHAKE128(inputBytes, outputByteLen):
return Keccak(1344, 256, inputBytes, 0x1F, outputByteLen)
def SHAKE256(inputBytes, outputByteLen):
return Keccak(1088, 512, inputBytes, 0x1F, outputByteLen)
def SHA3_224(inputBytes):
return Keccak(1152, 448, inputBytes, 0x06, 224//8)
def SHA3_256(inputBytes):
return Keccak(1088, 512, inputBytes, 0x06, 256//8)
def SHA3_384(inputBytes):
return Keccak(832, 768, inputBytes, 0x06, 384//8)
def SHA3_512(inputBytes):
return Keccak(576, 1024, inputBytes, 0x06, 512//8)

View File

@ -34,15 +34,30 @@ hash_224_test() ->
?assertEqual(<<16#038907E89C919CD8F90A7FBC5A88FF9278108DAEF3EBCDA0CEB383E1:224>>,
sha3:hash(224, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_224_native_test() ->
?assertEqual(<<16#038907E89C919CD8F90A7FBC5A88FF9278108DAEF3EBCDA0CEB383E1:224>>,
sha3:kek(224, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_256_test() ->
?assertEqual(<<16#22BCE46032802AF0ABFACF3768F7BE04A34F5F01DF60F44FFD52D3CA937350C0:256>>,
sha3:hash(256, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_256_native_test() ->
?assertEqual(<<16#22BCE46032802AF0ABFACF3768F7BE04A34F5F01DF60F44FFD52D3CA937350C0:256>>,
sha3:kek(256, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_384_test() ->
?assertEqual(<<16#25FAC1ADECBE1B254976FE32C2FE78829B23D7D84316141ECD208D6806A9DB4352A014ADA4106BA0D210DDA0FD18E150:384>>,
sha3:hash(384, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_384_native_test() ->
?assertEqual(<<16#25FAC1ADECBE1B254976FE32C2FE78829B23D7D84316141ECD208D6806A9DB4352A014ADA4106BA0D210DDA0FD18E150:384>>,
sha3:kek(384, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_512_test() ->
?assertEqual(<<16#94EE7851163C39C3489373AA0BF885D95925EAD7484C586D2E0D01D9C8069D3C30E2EEA2DC63A91B517FE53E43A31D764A2154A2DA92876366B138ABC4406805:512>>,
sha3:hash(512, <<16#00112233445566778899AABBCCDDEEFF:128>>)).
hash_512_native_test() ->
?assertEqual(<<16#94EE7851163C39C3489373AA0BF885D95925EAD7484C586D2E0D01D9C8069D3C30E2EEA2DC63A91B517FE53E43A31D764A2154A2DA92876366B138ABC4406805:512>>,
sha3:kek(512, <<16#00112233445566778899AABBCCDDEEFF:128>>)).

17
zomp.meta Normal file
View File

@ -0,0 +1,17 @@
{name,"Erlang SHA-3/Keccak"}.
{type,lib}.
{modules,[]}.
{prefix,none}.
{author,"Craig Everett"}.
{desc,"SHA-3 and Keccak in NIF and native Erlang."}.
{package_id,{"otpr","sha3",{0,1,5}}}.
{deps,[]}.
{key_name,none}.
{a_email,"zxq9@zxq9.com"}.
{c_email,"tetsuya.suzuki@gmail.com"}.
{copyright,"SUZUKI Tetsuya"}.
{file_exts,[]}.
{license,"Apache-2.0"}.
{repo_url,"https://github.com/zxq9/erlang-sha3"}.
{tags,["aeternity","sha3","blockchain","keccak"]}.
{ws_url,[]}.

8
zomp_prep Executable file
View File

@ -0,0 +1,8 @@
#! /bin/bash
# This is a small pre-packaging source generation and include correction script that should be
# run before packaging this project for use with ZX/Zomp.
rm -rf _build
rm -f ebin/*.beam
rm -f rebar*