digest-keccak 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ /*
2
+ ---------------------------------------------------------------------------
3
+ Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
4
+
5
+ LICENSE TERMS
6
+
7
+ The redistribution and use of this software (with or without changes)
8
+ is allowed without the payment of fees or royalties provided that:
9
+
10
+ 1. source code distributions include the above copyright notice, this
11
+ list of conditions and the following disclaimer;
12
+
13
+ 2. binary distributions include the above copyright notice, this list
14
+ of conditions and the following disclaimer in their documentation;
15
+
16
+ 3. the name of the copyright holder is not used to endorse products
17
+ built using this software without specific written permission.
18
+
19
+ DISCLAIMER
20
+
21
+ This software is provided 'as is' with no explicit or implied warranties
22
+ in respect of its properties, including, but not limited to, correctness
23
+ and/or fitness for purpose.
24
+ ---------------------------------------------------------------------------
25
+ Issue Date: 20/12/2007
26
+ Changes for ARM 9/9/2010
27
+ */
28
+
29
+ #ifndef _BRG_ENDIAN_H
30
+ #define _BRG_ENDIAN_H
31
+
32
+ #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
33
+ #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
34
+
35
+ #if 0
36
+ /* Include files where endian defines and byteswap functions may reside */
37
+ #if defined( __sun )
38
+ # include <sys/isa_defs.h>
39
+ #elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
40
+ # include <sys/endian.h>
41
+ #elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
42
+ defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
43
+ # include <machine/endian.h>
44
+ #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
45
+ # if !defined( __MINGW32__ ) && !defined( _AIX )
46
+ # include <endian.h>
47
+ # if !defined( __BEOS__ )
48
+ # include <byteswap.h>
49
+ # endif
50
+ # endif
51
+ #endif
52
+ #endif
53
+
54
+ /* Now attempt to set the define for platform byte order using any */
55
+ /* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
56
+ /* seem to encompass most endian symbol definitions */
57
+
58
+ #if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
59
+ # if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
60
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
61
+ # elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
62
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
63
+ # endif
64
+ #elif defined( BIG_ENDIAN )
65
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
66
+ #elif defined( LITTLE_ENDIAN )
67
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
68
+ #endif
69
+
70
+ #if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
71
+ # if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
72
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
73
+ # elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
74
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
75
+ # endif
76
+ #elif defined( _BIG_ENDIAN )
77
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
78
+ #elif defined( _LITTLE_ENDIAN )
79
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
80
+ #endif
81
+
82
+ #if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
83
+ # if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
84
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
85
+ # elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
86
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
87
+ # endif
88
+ #elif defined( __BIG_ENDIAN )
89
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
90
+ #elif defined( __LITTLE_ENDIAN )
91
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
92
+ #endif
93
+
94
+ #if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
95
+ # if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
96
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
97
+ # elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
98
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
99
+ # endif
100
+ #elif defined( __BIG_ENDIAN__ )
101
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
102
+ #elif defined( __LITTLE_ENDIAN__ )
103
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
104
+ #endif
105
+
106
+ /* if the platform byte order could not be determined, then try to */
107
+ /* set this define using common machine defines */
108
+ #if !defined(PLATFORM_BYTE_ORDER)
109
+
110
+ #if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
111
+ defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
112
+ defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
113
+ defined( vax ) || defined( vms ) || defined( VMS ) || \
114
+ defined( __VMS ) || defined( _M_X64 )
115
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
116
+
117
+ #elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
118
+ defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
119
+ defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
120
+ defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
121
+ defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
122
+ defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
123
+ defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
124
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
125
+
126
+ #elif defined(__arm__)
127
+ # ifdef __BIG_ENDIAN
128
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
129
+ # else
130
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
131
+ # endif
132
+ #elif 1 /* **** EDIT HERE IF NECESSARY **** */
133
+ # define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
134
+ #elif 0 /* **** EDIT HERE IF NECESSARY **** */
135
+ # define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
136
+ #else
137
+ # error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order
138
+ #endif
139
+
140
+ #endif
141
+
142
+ #endif
@@ -0,0 +1,117 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #include <stdio.h>
15
+ #include "displayIntermediateValues.h"
16
+ #include "KeccakNISTInterface.h"
17
+
18
+ FILE *intermediateValueFile = 0;
19
+ int displayLevel = 0;
20
+
21
+ void displaySetIntermediateValueFile(FILE *f)
22
+ {
23
+ intermediateValueFile = f;
24
+ }
25
+
26
+ void displaySetLevel(int level)
27
+ {
28
+ displayLevel = level;
29
+ }
30
+
31
+ void displayBytes(int level, const char *text, const unsigned char *bytes, unsigned int size)
32
+ {
33
+ unsigned int i;
34
+
35
+ if ((intermediateValueFile) && (level <= displayLevel)) {
36
+ fprintf(intermediateValueFile, "%s:\n", text);
37
+ for(i=0; i<size; i++)
38
+ fprintf(intermediateValueFile, "%02X ", bytes[i]);
39
+ fprintf(intermediateValueFile, "\n");
40
+ fprintf(intermediateValueFile, "\n");
41
+ }
42
+ }
43
+
44
+ void displayBits(int level, const char *text, const unsigned char *data, unsigned int size, int MSBfirst)
45
+ {
46
+ unsigned int i, iByte, iBit;
47
+
48
+ if ((intermediateValueFile) && (level <= displayLevel)) {
49
+ fprintf(intermediateValueFile, "%s:\n", text);
50
+ for(i=0; i<size; i++) {
51
+ iByte = i/8;
52
+ iBit = i%8;
53
+ if (MSBfirst)
54
+ fprintf(intermediateValueFile, "%d ", ((data[iByte] << iBit) & 0x80) != 0);
55
+ else
56
+ fprintf(intermediateValueFile, "%d ", ((data[iByte] >> iBit) & 0x01) != 0);
57
+ }
58
+ fprintf(intermediateValueFile, "\n");
59
+ fprintf(intermediateValueFile, "\n");
60
+ }
61
+ }
62
+
63
+ void displayStateAsBytes(int level, const char *text, const unsigned char *state)
64
+ {
65
+ displayBytes(level, text, state, KeccakPermutationSizeInBytes);
66
+ }
67
+
68
+ void displayStateAs32bitWords(int level, const char *text, const unsigned int *state)
69
+ {
70
+ unsigned int i;
71
+
72
+ if ((intermediateValueFile) && (level <= displayLevel)) {
73
+ fprintf(intermediateValueFile, "%s:\n", text);
74
+ for(i=0; i<KeccakPermutationSize/64; i++) {
75
+ fprintf(intermediateValueFile, "%08X:%08X", (unsigned int)state[2*i+0], (unsigned int)state[2*i+1]);
76
+ if ((i%5) == 4)
77
+ fprintf(intermediateValueFile, "\n");
78
+ else
79
+ fprintf(intermediateValueFile, " ");
80
+ }
81
+ }
82
+ }
83
+
84
+ void displayStateAs64bitWords(int level, const char *text, const unsigned long long int *state)
85
+ {
86
+ unsigned int i;
87
+
88
+ if ((intermediateValueFile) && (level <= displayLevel)) {
89
+ fprintf(intermediateValueFile, "%s:\n", text);
90
+ for(i=0; i<KeccakPermutationSize/64; i++) {
91
+ fprintf(intermediateValueFile, "%08X", (unsigned int)(state[i] >> 32));
92
+ fprintf(intermediateValueFile, "%08X", (unsigned int)(state[i] & 0xFFFFFFFFULL));
93
+ if ((i%5) == 4)
94
+ fprintf(intermediateValueFile, "\n");
95
+ else
96
+ fprintf(intermediateValueFile, " ");
97
+ }
98
+ }
99
+ }
100
+
101
+ void displayRoundNumber(int level, unsigned int i)
102
+ {
103
+ if ((intermediateValueFile) && (level <= displayLevel)) {
104
+ fprintf(intermediateValueFile, "\n");
105
+ fprintf(intermediateValueFile, "--- Round %d ---\n", i);
106
+ fprintf(intermediateValueFile, "\n");
107
+ }
108
+ }
109
+
110
+ void displayText(int level, const char *text)
111
+ {
112
+ if ((intermediateValueFile) && (level <= displayLevel)) {
113
+ fprintf(intermediateValueFile, text);
114
+ fprintf(intermediateValueFile, "\n");
115
+ fprintf(intermediateValueFile, "\n");
116
+ }
117
+ }
@@ -0,0 +1,29 @@
1
+ /*
2
+ The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
3
+ Michaël Peeters and Gilles Van Assche. For more information, feedback or
4
+ questions, please refer to our website: http://keccak.noekeon.org/
5
+
6
+ Implementation by the designers,
7
+ hereby denoted as "the implementer".
8
+
9
+ To the extent possible under law, the implementer has waived all copyright
10
+ and related or neighboring rights to the source code in this file.
11
+ http://creativecommons.org/publicdomain/zero/1.0/
12
+ */
13
+
14
+ #ifndef _displayIntermediateValues_h_
15
+ #define _displayIntermediateValues_h_
16
+
17
+ #include <stdio.h>
18
+
19
+ void displaySetIntermediateValueFile(FILE *f);
20
+ void displaySetLevel(int level);
21
+ void displayBytes(int level, const char *text, const unsigned char *bytes, unsigned int size);
22
+ void displayBits(int level, const char *text, const unsigned char *data, unsigned int size, int MSBfirst);
23
+ void displayStateAsBytes(int level, const char *text, const unsigned char *state);
24
+ void displayStateAs32bitWords(int level, const char *text, const unsigned int *state);
25
+ void displayStateAs64bitWords(int level, const char *text, const unsigned long long int *state);
26
+ void displayRoundNumber(int level, unsigned int i);
27
+ void displayText(int level, const char *text);
28
+
29
+ #endif
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+
5
+ have_header('ruby/digest.h')
6
+ have_func('rb_str_set_len')
7
+
8
+ $CFLAGS << " -fvisibility=hidden"
9
+ create_makefile('digest/keccak')
@@ -0,0 +1,153 @@
1
+ #include "ruby.h"
2
+ #ifdef HAVE_RUBY_DIGEST_H
3
+ #include "ruby/digest.h"
4
+ #else
5
+ #include "digest.h"
6
+ #endif
7
+ #include "KeccakNISTInterface.h"
8
+
9
+ #define MAX_DIGEST_SIZE 64
10
+ #define DEFAULT_DIGEST_LEN 512
11
+
12
+ static int keccak_init_func(hashState *ctx);
13
+ static void keccak_update_func(hashState *ctx, unsigned char *str, size_t len);
14
+ static int keccak_finish_func(hashState *ctx, unsigned char *digest);
15
+
16
+ /*
17
+ Metadata definition for the Keccak algorithm.
18
+ Defines the Version, sizes for block and digest as well as
19
+ the entry points for the algorithms
20
+ */
21
+ static rb_digest_metadata_t keccak = {
22
+ RUBY_DIGEST_API_VERSION,
23
+ DEFAULT_DIGEST_LEN,
24
+ KeccakPermutationSize - (2 * DEFAULT_DIGEST_LEN), //size of blocks
25
+ sizeof(hashState), //size of context for the object we'll be passed in below functions.
26
+ (rb_digest_hash_init_func_t)keccak_init_func,
27
+ (rb_digest_hash_update_func_t)keccak_update_func,
28
+ (rb_digest_hash_finish_func_t)keccak_finish_func,
29
+ };
30
+
31
+ /* Initialization function for the algorithm,
32
+ gets called during allocation of the digest object.
33
+ we override initialize to do custom hash size, so we don't care too much here.
34
+ */
35
+ static int
36
+ keccak_init_func(hashState *ctx) {
37
+ // Just return a 1 ' successful' we override the init function
38
+ // so this is not necessary
39
+ // the base class alloc calls this to initialize the algorithm
40
+ return 1;
41
+ }
42
+
43
+ /* Update function, take the current context and add str to it */
44
+ static void
45
+ keccak_update_func(hashState *ctx, unsigned char *str, size_t len) {
46
+ Update(ctx, str, len * 8);
47
+ }
48
+
49
+ /* Finish the hash calculation and return the finished string */
50
+ static int
51
+ keccak_finish_func(hashState *ctx, unsigned char *digest) {
52
+ Final(ctx, digest);
53
+ return 1;
54
+ }
55
+
56
+ /* Ruby method. Digest::Keccak#finish()
57
+ * No Arguments
58
+ * @returns [String] Encoded Digest String
59
+ */
60
+ static VALUE
61
+ rb_keccak_finish(VALUE self) {
62
+ hashState *ctx;
63
+ VALUE digest;
64
+
65
+ ctx = (hashState *)RTYPEDDATA_DATA(self);
66
+ digest = rb_str_new(0, ctx->capacity / 2 / 8);
67
+ keccak_finish_func(ctx, (unsigned char *)RSTRING_PTR(digest));
68
+
69
+ return digest;
70
+ }
71
+
72
+ /* :nodoc: private method
73
+ * initialize the ctx with the bitlength
74
+ */
75
+ static void
76
+ keccak_init(hashState *ctx, size_t bitlen) {
77
+ switch (Init(ctx, bitlen)) {
78
+ case SUCCESS:
79
+ return;
80
+ case FAIL:
81
+ rb_raise(rb_eRuntimeError, "Unknown error");
82
+ case BAD_HASHLEN:
83
+ rb_raise(rb_eArgError, "Bad hash length (must be 0, 224, 256, 384 or 512)");
84
+ default:
85
+ rb_raise(rb_eRuntimeError, "Unknown error code");
86
+ }
87
+ }
88
+
89
+ /* Ruby method. Digest::Keccak.new(hashlen)
90
+ * @param hashlen The length of hash, only supports 224, 256, 384 or 512
91
+ * @returns [Digest::Keccak] new object.
92
+ */
93
+ static VALUE
94
+ rb_keccak_initialize(int argc, VALUE *argv, VALUE self) {
95
+ hashState *ctx;
96
+ VALUE hashlen;
97
+ int i_hashlen;
98
+
99
+ if (rb_scan_args(argc, argv, "01", &hashlen) == 0) {
100
+ i_hashlen = DEFAULT_DIGEST_LEN;
101
+ } else {
102
+ i_hashlen = NUM2INT(hashlen);
103
+ }
104
+ if ( i_hashlen == 0) {
105
+ rb_raise(rb_eArgError, "Unsupported hash length");
106
+ }
107
+
108
+ ctx = (hashState *)RTYPEDDATA_DATA(self);
109
+ keccak_init(ctx, i_hashlen);
110
+
111
+ return rb_call_super(0, NULL);
112
+ }
113
+
114
+ /* Ruby method. Digest::Keccak#digest_length
115
+ * @returns [Numeric] Length of the digest.
116
+ */
117
+ static VALUE
118
+ rb_keccak_digest_length(VALUE self) {
119
+ hashState *ctx;
120
+
121
+ ctx = (hashState *)RTYPEDDATA_DATA(self);
122
+ return INT2FIX(ctx->capacity / 2 / 8);
123
+ }
124
+
125
+ /* Ruby method. Digest::Keccak#block_length
126
+ * @returns [Numeric] Length of blocks in this digest.
127
+ */
128
+ static VALUE
129
+ rb_keccak_block_length(VALUE self) {
130
+ hashState *ctx;
131
+
132
+ ctx = (hashState *)RTYPEDDATA_DATA(self);
133
+ return INT2FIX(ctx->rate / 8);
134
+ }
135
+
136
+ void __attribute__((visibility("default")))
137
+ Init_keccak() {
138
+ VALUE mDigest, cDigest_Base, cKeccak;
139
+
140
+ rb_require("digest");
141
+
142
+ mDigest = rb_path2class("Digest");
143
+ cDigest_Base = rb_path2class("Digest::Base");
144
+
145
+ cKeccak = rb_define_class_under(mDigest, "Keccak", cDigest_Base);
146
+
147
+ rb_iv_set(cKeccak, "metadata", Data_Wrap_Struct(0, 0, 0, (void *)&keccak));
148
+
149
+ rb_define_method(cKeccak, "initialize", rb_keccak_initialize, -1);
150
+ rb_define_method(cKeccak, "digest_length", rb_keccak_digest_length, 0);
151
+ rb_define_method(cKeccak, "block_length", rb_keccak_block_length, 0);
152
+ rb_define_method(cKeccak, "finish", rb_keccak_finish, 0);
153
+ }