digest-sha3 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +9 -0
- data/Makefile +18 -0
- data/README.md +50 -0
- data/digest-sha3.gemspec +21 -0
- data/ext/digest/KeccakF-1600-int-set.h +6 -0
- data/ext/digest/KeccakF-1600-interface.h +46 -0
- data/ext/digest/KeccakF-1600-reference.c +300 -0
- data/ext/digest/KeccakNISTInterface.c +81 -0
- data/ext/digest/KeccakNISTInterface.h +70 -0
- data/ext/digest/KeccakSponge.c +266 -0
- data/ext/digest/KeccakSponge.h +76 -0
- data/ext/digest/brg_endian.h +142 -0
- data/ext/digest/displayIntermediateValues.c +117 -0
- data/ext/digest/displayIntermediateValues.h +29 -0
- data/ext/digest/extconf.rb +3 -0
- data/ext/digest/sha3.c +137 -0
- data/lib/digest/sha3/helpers.rb +20 -0
- data/lib/digest/sha3/version.rb +7 -0
- metadata +64 -0
@@ -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
|
data/ext/digest/sha3.c
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "KeccakNISTInterface.h"
|
3
|
+
|
4
|
+
#define MAX_DIGEST_SIZE 64
|
5
|
+
|
6
|
+
static VALUE mDigest, cSHA3;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
hashState state;
|
10
|
+
int bitlen;
|
11
|
+
} RbSHA3;
|
12
|
+
|
13
|
+
static VALUE
|
14
|
+
rb_sha3_alloc(VALUE klass) {
|
15
|
+
RbSHA3 *ctx;
|
16
|
+
|
17
|
+
ctx = (RbSHA3 *) xmalloc(sizeof(RbSHA3));
|
18
|
+
ctx->bitlen = -1;
|
19
|
+
return Data_Wrap_Struct(klass, 0, xfree, ctx);
|
20
|
+
}
|
21
|
+
|
22
|
+
static VALUE
|
23
|
+
rb_sha3_initialize(int argc, VALUE *argv, VALUE self) {
|
24
|
+
RbSHA3 *ctx;
|
25
|
+
VALUE hashlen;
|
26
|
+
int i_hashlen;
|
27
|
+
|
28
|
+
if (rb_scan_args(argc, argv, "01", &hashlen) == 0) {
|
29
|
+
i_hashlen = 512;
|
30
|
+
} else {
|
31
|
+
i_hashlen = NUM2INT(hashlen);
|
32
|
+
}
|
33
|
+
if (i_hashlen == 0) {
|
34
|
+
rb_raise(rb_eRuntimeError, "Unsupported hash length");
|
35
|
+
}
|
36
|
+
|
37
|
+
Data_Get_Struct(self, RbSHA3, ctx);
|
38
|
+
ctx->bitlen = i_hashlen;
|
39
|
+
|
40
|
+
switch (Init(&ctx->state, i_hashlen)) {
|
41
|
+
case SUCCESS:
|
42
|
+
return self;
|
43
|
+
case FAIL:
|
44
|
+
rb_raise(rb_eRuntimeError, "Unknown error");
|
45
|
+
return Qnil;
|
46
|
+
case BAD_HASHLEN:
|
47
|
+
rb_raise(rb_eRuntimeError, "Bad hash length (must be 0, 224, 256, 384 or 512)");
|
48
|
+
return Qnil;
|
49
|
+
default:
|
50
|
+
rb_raise(rb_eRuntimeError, "Unknown error code");
|
51
|
+
return Qnil;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE
|
56
|
+
rb_sha3_initialize_copy(VALUE self, VALUE other) {
|
57
|
+
RbSHA3 *ctx_self, *ctx_other;
|
58
|
+
|
59
|
+
rb_check_frozen(self);
|
60
|
+
Data_Get_Struct(self, RbSHA3, ctx_self);
|
61
|
+
Data_Get_Struct(other, RbSHA3, ctx_other);
|
62
|
+
memcpy(&ctx_self->state, &ctx_other->state, sizeof(hashState));
|
63
|
+
ctx_self->bitlen = ctx_other->bitlen;
|
64
|
+
return self;
|
65
|
+
}
|
66
|
+
|
67
|
+
static VALUE
|
68
|
+
rb_sha3_reset(VALUE self) {
|
69
|
+
RbSHA3 *ctx;
|
70
|
+
|
71
|
+
Data_Get_Struct(self, RbSHA3, ctx);
|
72
|
+
Init(&ctx->state, ctx->bitlen);
|
73
|
+
return self;
|
74
|
+
}
|
75
|
+
|
76
|
+
static VALUE
|
77
|
+
rb_sha3_update(VALUE self, VALUE str) {
|
78
|
+
RbSHA3 *ctx;
|
79
|
+
|
80
|
+
Data_Get_Struct(self, RbSHA3, ctx);
|
81
|
+
Update(&ctx->state, RSTRING_PTR(str), RSTRING_LEN(str) * 8);
|
82
|
+
return self;
|
83
|
+
}
|
84
|
+
|
85
|
+
static VALUE
|
86
|
+
rb_sha3_digest(VALUE self, VALUE str) {
|
87
|
+
RbSHA3 *ctx;
|
88
|
+
hashState state;
|
89
|
+
unsigned char digest[MAX_DIGEST_SIZE];
|
90
|
+
|
91
|
+
Data_Get_Struct(self, RbSHA3, ctx);
|
92
|
+
memcpy(&state, &ctx->state, sizeof(hashState));
|
93
|
+
Final(&state, digest);
|
94
|
+
return rb_str_new((const char *) digest, ctx->bitlen / 8);
|
95
|
+
}
|
96
|
+
|
97
|
+
static VALUE
|
98
|
+
rb_sha3_singleton_digest(int argc, VALUE *argv, VALUE klass) {
|
99
|
+
VALUE data, hashlen;
|
100
|
+
int i_hashlen;
|
101
|
+
unsigned char digest[MAX_DIGEST_SIZE];
|
102
|
+
|
103
|
+
if (rb_scan_args(argc, argv, "11", &data, &hashlen) == 1) {
|
104
|
+
i_hashlen = 512;
|
105
|
+
} else {
|
106
|
+
i_hashlen = NUM2INT(hashlen);
|
107
|
+
}
|
108
|
+
|
109
|
+
switch (Hash(i_hashlen, RSTRING_PTR(data), RSTRING_LEN(data) * 8, digest)) {
|
110
|
+
case SUCCESS:
|
111
|
+
return rb_str_new(digest, i_hashlen / 8);
|
112
|
+
case FAIL:
|
113
|
+
rb_raise(rb_eRuntimeError, "Unknown error");
|
114
|
+
return Qnil;
|
115
|
+
case BAD_HASHLEN:
|
116
|
+
rb_raise(rb_eRuntimeError, "Bad hash length (must be 0, 224, 256, 384 or 512)");
|
117
|
+
return Qnil;
|
118
|
+
default:
|
119
|
+
rb_raise(rb_eRuntimeError, "Unknown error code");
|
120
|
+
return Qnil;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
void __attribute__((visibility("default")))
|
125
|
+
Init_sha3() {
|
126
|
+
mDigest = rb_define_module("Digest");
|
127
|
+
cSHA3 = rb_define_class_under(mDigest, "SHA3", rb_cObject);
|
128
|
+
rb_define_alloc_func(cSHA3, rb_sha3_alloc);
|
129
|
+
rb_define_method(cSHA3, "initialize", rb_sha3_initialize, -1);
|
130
|
+
rb_define_method(cSHA3, "initialize_copy", rb_sha3_initialize_copy, 1);
|
131
|
+
rb_define_method(cSHA3, "reset", rb_sha3_reset, 0);
|
132
|
+
rb_define_method(cSHA3, "update", rb_sha3_update, 1);
|
133
|
+
rb_define_method(cSHA3, "<<", rb_sha3_update, 1);
|
134
|
+
rb_define_method(cSHA3, "digest", rb_sha3_digest, 0);
|
135
|
+
rb_define_singleton_method(cSHA3, "digest", rb_sha3_singleton_digest, -1);
|
136
|
+
rb_require("digest/sha3/helpers");
|
137
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: ascii
|
2
|
+
Digest::SHA3.class_eval do
|
3
|
+
def self.hexdigest(*args)
|
4
|
+
force_ascii(digest(*args).unpack("H*").first)
|
5
|
+
end
|
6
|
+
|
7
|
+
def hexdigest
|
8
|
+
Digest::SHA3.force_ascii(digest.unpack("H*").first)
|
9
|
+
end
|
10
|
+
|
11
|
+
if ''.respond_to?(:force_encoding)
|
12
|
+
def self.force_ascii(str)
|
13
|
+
str.force_encoding('ascii')
|
14
|
+
end
|
15
|
+
else
|
16
|
+
def self.force_ascii(str)
|
17
|
+
str
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|