1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00
This commit is contained in:
Pavol Rusnak 2016-04-20 19:40:08 +02:00
parent 92fcafa9e9
commit f8713bad4d
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
10 changed files with 719 additions and 2 deletions

View File

@ -61,7 +61,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha256_digest_obj, mod_TrezorC
STATIC mp_obj_t mod_TrezorCrypto_Sha256___del__(mp_obj_t self) { STATIC mp_obj_t mod_TrezorCrypto_Sha256___del__(mp_obj_t self) {
mp_obj_Sha256_t *o = MP_OBJ_TO_PTR(self); mp_obj_Sha256_t *o = MP_OBJ_TO_PTR(self);
mbedtls_sha256_free(&(o->ctx)); mbedtls_sha256_free(&(o->ctx));
printf("yay!\n");
return mp_const_none; return mp_const_none;
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha256___del___obj, mod_TrezorCrypto_Sha256___del__); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha256___del___obj, mod_TrezorCrypto_Sha256___del__);

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) Pavol Rusnak, SatoshiLabs
*
* Licensed under Microsoft Reference Source License (Ms-RSL)
* see LICENSE.md file for details
*/
#include "py/objstr.h"
#include "sha3.h"
#define HASH_SHA3_256_BLOCK_SIZE 64
#define HASH_SHA3_256_DIGEST_SIZE 32
// class Sha3_256(object):
typedef struct _mp_obj_Sha3_256_t {
mp_obj_base_t base;
sha3_ctx ctx;
} mp_obj_Sha3_256_t;
STATIC mp_obj_t mod_TrezorCrypto_Sha3_256_update(mp_obj_t self, mp_obj_t data);
// def Sha3_256.__init__(self, data: bytes = None)
STATIC mp_obj_t mod_TrezorCrypto_Sha3_256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Sha3_256_t *o = m_new_obj(mp_obj_Sha3_256_t);
o->base.type = type;
rhash_sha3_256_init(&(o->ctx));
// constructor called with bytes/str as first parameter
if (n_args == 1) {
mod_TrezorCrypto_Sha3_256_update(MP_OBJ_FROM_PTR(o), args[0]);
}
return MP_OBJ_FROM_PTR(o);
}
// def Sha3_256.update(self, data: bytes) -> None
STATIC mp_obj_t mod_TrezorCrypto_Sha3_256_update(mp_obj_t self, mp_obj_t data) {
mp_obj_Sha3_256_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t databuf;
mp_get_buffer_raise(data, &databuf, MP_BUFFER_READ);
rhash_sha3_update(&(o->ctx), databuf.buf, databuf.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_TrezorCrypto_Sha3_256_update_obj, mod_TrezorCrypto_Sha3_256_update);
// def Sha3_256.digest(self) -> bytes
STATIC mp_obj_t mod_TrezorCrypto_Sha3_256_digest(mp_obj_t self) {
mp_obj_Sha3_256_t *o = MP_OBJ_TO_PTR(self);
vstr_t vstr;
vstr_init_len(&vstr, HASH_SHA3_256_DIGEST_SIZE);
sha3_ctx ctx;
memcpy(&ctx, &(o->ctx), sizeof(sha3_ctx));
rhash_sha3_final(&ctx, (uint8_t *)vstr.buf);
memset(&ctx, 0, sizeof(sha3_ctx));
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha3_256_digest_obj, mod_TrezorCrypto_Sha3_256_digest);
// def Sha3_256.__del__(self) -> None
STATIC mp_obj_t mod_TrezorCrypto_Sha3_256___del__(mp_obj_t self) {
mp_obj_Sha3_256_t *o = MP_OBJ_TO_PTR(self);
memset(&(o->ctx), 0, sizeof(sha3_ctx));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha3_256___del___obj, mod_TrezorCrypto_Sha3_256___del__);
// Sha3_256 stuff
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Sha3_256_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_256_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_256_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_256___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(HASH_SHA3_256_BLOCK_SIZE) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(HASH_SHA3_256_DIGEST_SIZE) },
};
STATIC MP_DEFINE_CONST_DICT(mod_TrezorCrypto_Sha3_256_locals_dict, mod_TrezorCrypto_Sha3_256_locals_dict_table);
STATIC const mp_obj_type_t mod_TrezorCrypto_Sha3_256_type = {
{ &mp_type_type },
.name = MP_QSTR_Sha3_256,
.make_new = mod_TrezorCrypto_Sha3_256_make_new,
.locals_dict = (void*)&mod_TrezorCrypto_Sha3_256_locals_dict,
};

View File

@ -0,0 +1,83 @@
/*
* Copyright (c) Pavol Rusnak, SatoshiLabs
*
* Licensed under Microsoft Reference Source License (Ms-RSL)
* see LICENSE.md file for details
*/
#include "py/objstr.h"
#include "sha3.h"
#define HASH_SHA3_512_BLOCK_SIZE 128
#define HASH_SHA3_512_DIGEST_SIZE 64
// class Sha3_512(object):
typedef struct _mp_obj_Sha3_512_t {
mp_obj_base_t base;
sha3_ctx ctx;
} mp_obj_Sha3_512_t;
STATIC mp_obj_t mod_TrezorCrypto_Sha3_512_update(mp_obj_t self, mp_obj_t data);
// def Sha3_512.__init__(self, data: bytes = None)
STATIC mp_obj_t mod_TrezorCrypto_Sha3_512_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 0, 1, false);
mp_obj_Sha3_512_t *o = m_new_obj(mp_obj_Sha3_512_t);
o->base.type = type;
rhash_sha3_512_init(&(o->ctx));
// constructor called with bytes/str as first parameter
if (n_args == 1) {
mod_TrezorCrypto_Sha3_512_update(MP_OBJ_FROM_PTR(o), args[0]);
}
return MP_OBJ_FROM_PTR(o);
}
// def Sha3_512.update(self, data: bytes) -> None
STATIC mp_obj_t mod_TrezorCrypto_Sha3_512_update(mp_obj_t self, mp_obj_t data) {
mp_obj_Sha3_512_t *o = MP_OBJ_TO_PTR(self);
mp_buffer_info_t databuf;
mp_get_buffer_raise(data, &databuf, MP_BUFFER_READ);
rhash_sha3_update(&(o->ctx), databuf.buf, databuf.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_TrezorCrypto_Sha3_512_update_obj, mod_TrezorCrypto_Sha3_512_update);
// def Sha3_512.digest(self) -> bytes
STATIC mp_obj_t mod_TrezorCrypto_Sha3_512_digest(mp_obj_t self) {
mp_obj_Sha3_512_t *o = MP_OBJ_TO_PTR(self);
vstr_t vstr;
vstr_init_len(&vstr, HASH_SHA3_512_DIGEST_SIZE);
sha3_ctx ctx;
memcpy(&ctx, &(o->ctx), sizeof(sha3_ctx));
rhash_sha3_final(&ctx, (uint8_t *)vstr.buf);
memset(&ctx, 0, sizeof(sha3_ctx));
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha3_512_digest_obj, mod_TrezorCrypto_Sha3_512_digest);
// def Sha3_512.__del__(self) -> None
STATIC mp_obj_t mod_TrezorCrypto_Sha3_512___del__(mp_obj_t self) {
mp_obj_Sha3_512_t *o = MP_OBJ_TO_PTR(self);
memset(&(o->ctx), 0, sizeof(sha3_ctx));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_TrezorCrypto_Sha3_512___del___obj, mod_TrezorCrypto_Sha3_512___del__);
// Sha3_512 stuff
STATIC const mp_rom_map_elem_t mod_TrezorCrypto_Sha3_512_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_512_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_512_digest_obj) },
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_512___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_block_size), MP_OBJ_NEW_SMALL_INT(HASH_SHA3_512_BLOCK_SIZE) },
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_OBJ_NEW_SMALL_INT(HASH_SHA3_512_DIGEST_SIZE) },
};
STATIC MP_DEFINE_CONST_DICT(mod_TrezorCrypto_Sha3_512_locals_dict, mod_TrezorCrypto_Sha3_512_locals_dict_table);
STATIC const mp_obj_type_t mod_TrezorCrypto_Sha3_512_type = {
{ &mp_type_type },
.name = MP_QSTR_Sha3_512,
.make_new = mod_TrezorCrypto_Sha3_512_make_new,
.locals_dict = (void*)&mod_TrezorCrypto_Sha3_512_locals_dict,
};

View File

@ -19,6 +19,8 @@
#include "modtrezorcrypto-ripemd160.h" #include "modtrezorcrypto-ripemd160.h"
#include "modtrezorcrypto-sha256.h" #include "modtrezorcrypto-sha256.h"
#include "modtrezorcrypto-sha512.h" #include "modtrezorcrypto-sha512.h"
#include "modtrezorcrypto-sha3-256.h"
#include "modtrezorcrypto-sha3-512.h"
// module stuff // module stuff
@ -27,6 +29,8 @@ STATIC const mp_rom_map_elem_t mp_module_TrezorCrypto_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_Ripemd160), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_type) }, { MP_ROM_QSTR(MP_QSTR_Ripemd160), MP_ROM_PTR(&mod_TrezorCrypto_Ripemd160_type) },
{ MP_ROM_QSTR(MP_QSTR_Sha256), MP_ROM_PTR(&mod_TrezorCrypto_Sha256_type) }, { MP_ROM_QSTR(MP_QSTR_Sha256), MP_ROM_PTR(&mod_TrezorCrypto_Sha256_type) },
{ MP_ROM_QSTR(MP_QSTR_Sha512), MP_ROM_PTR(&mod_TrezorCrypto_Sha512_type) }, { MP_ROM_QSTR(MP_QSTR_Sha512), MP_ROM_PTR(&mod_TrezorCrypto_Sha512_type) },
{ MP_ROM_QSTR(MP_QSTR_Sha3_256), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_256_type) },
{ MP_ROM_QSTR(MP_QSTR_Sha3_512), MP_ROM_PTR(&mod_TrezorCrypto_Sha3_512_type) },
{ MP_ROM_QSTR(MP_QSTR_pbkdf2_hmac), MP_ROM_PTR(&mod_TrezorCrypto_pbkdf2_hmac_obj) }, { MP_ROM_QSTR(MP_QSTR_pbkdf2_hmac), MP_ROM_PTR(&mod_TrezorCrypto_pbkdf2_hmac_obj) },
}; };
STATIC MP_DEFINE_CONST_DICT(mp_module_TrezorCrypto_globals, mp_module_TrezorCrypto_globals_table); STATIC MP_DEFINE_CONST_DICT(mp_module_TrezorCrypto_globals, mp_module_TrezorCrypto_globals_table);

View File

@ -0,0 +1,361 @@
/* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
* based on the
* The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
* by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
*
* Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
*/
#include <assert.h>
#include <string.h>
#include "sha3.h"
#define I64(x) x##LL
#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
#define le2me_64(x) (x)
#define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0)))
# define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
/* constants */
#define NumberOfRounds 24
/* SHA3 (Keccak) constants for 24 rounds */
static uint64_t keccak_round_constants[NumberOfRounds] = {
I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000),
I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009),
I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A),
I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003),
I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A),
I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008)
};
/* Initializing a sha3 context for given number of output bits */
static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits)
{
/* NB: The Keccak capacity parameter = bits * 2 */
unsigned rate = 1600 - bits * 2;
memset(ctx, 0, sizeof(sha3_ctx));
ctx->block_size = rate / 8;
assert(rate <= 1600 && (rate % 64) == 0);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_224_init(sha3_ctx *ctx)
{
rhash_keccak_init(ctx, 224);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_256_init(sha3_ctx *ctx)
{
rhash_keccak_init(ctx, 256);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_384_init(sha3_ctx *ctx)
{
rhash_keccak_init(ctx, 384);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_512_init(sha3_ctx *ctx)
{
rhash_keccak_init(ctx, 512);
}
/* Keccak theta() transformation */
static void keccak_theta(uint64_t *A)
{
unsigned int x;
uint64_t C[5], D[5];
for (x = 0; x < 5; x++) {
C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
}
D[0] = ROTL64(C[1], 1) ^ C[4];
D[1] = ROTL64(C[2], 1) ^ C[0];
D[2] = ROTL64(C[3], 1) ^ C[1];
D[3] = ROTL64(C[4], 1) ^ C[2];
D[4] = ROTL64(C[0], 1) ^ C[3];
for (x = 0; x < 5; x++) {
A[x] ^= D[x];
A[x + 5] ^= D[x];
A[x + 10] ^= D[x];
A[x + 15] ^= D[x];
A[x + 20] ^= D[x];
}
}
/* Keccak pi() transformation */
static void keccak_pi(uint64_t *A)
{
uint64_t A1;
A1 = A[1];
A[ 1] = A[ 6];
A[ 6] = A[ 9];
A[ 9] = A[22];
A[22] = A[14];
A[14] = A[20];
A[20] = A[ 2];
A[ 2] = A[12];
A[12] = A[13];
A[13] = A[19];
A[19] = A[23];
A[23] = A[15];
A[15] = A[ 4];
A[ 4] = A[24];
A[24] = A[21];
A[21] = A[ 8];
A[ 8] = A[16];
A[16] = A[ 5];
A[ 5] = A[ 3];
A[ 3] = A[18];
A[18] = A[17];
A[17] = A[11];
A[11] = A[ 7];
A[ 7] = A[10];
A[10] = A1;
/* note: A[ 0] is left as is */
}
/* Keccak chi() transformation */
static void keccak_chi(uint64_t *A)
{
int i;
for (i = 0; i < 25; i += 5) {
uint64_t A0 = A[0 + i], A1 = A[1 + i];
A[0 + i] ^= ~A1 & A[2 + i];
A[1 + i] ^= ~A[2 + i] & A[3 + i];
A[2 + i] ^= ~A[3 + i] & A[4 + i];
A[3 + i] ^= ~A[4 + i] & A0;
A[4 + i] ^= ~A0 & A1;
}
}
static void rhash_sha3_permutation(uint64_t *state)
{
int round;
for (round = 0; round < NumberOfRounds; round++)
{
keccak_theta(state);
/* apply Keccak rho() transformation */
state[ 1] = ROTL64(state[ 1], 1);
state[ 2] = ROTL64(state[ 2], 62);
state[ 3] = ROTL64(state[ 3], 28);
state[ 4] = ROTL64(state[ 4], 27);
state[ 5] = ROTL64(state[ 5], 36);
state[ 6] = ROTL64(state[ 6], 44);
state[ 7] = ROTL64(state[ 7], 6);
state[ 8] = ROTL64(state[ 8], 55);
state[ 9] = ROTL64(state[ 9], 20);
state[10] = ROTL64(state[10], 3);
state[11] = ROTL64(state[11], 10);
state[12] = ROTL64(state[12], 43);
state[13] = ROTL64(state[13], 25);
state[14] = ROTL64(state[14], 39);
state[15] = ROTL64(state[15], 41);
state[16] = ROTL64(state[16], 45);
state[17] = ROTL64(state[17], 15);
state[18] = ROTL64(state[18], 21);
state[19] = ROTL64(state[19], 8);
state[20] = ROTL64(state[20], 18);
state[21] = ROTL64(state[21], 2);
state[22] = ROTL64(state[22], 61);
state[23] = ROTL64(state[23], 56);
state[24] = ROTL64(state[24], 14);
keccak_pi(state);
keccak_chi(state);
/* apply iota(state, round) */
*state ^= keccak_round_constants[round];
}
}
/**
* The core transformation. Process the specified block of data.
*
* @param hash the algorithm state
* @param block the message block to process
* @param block_size the size of the processed block in bytes
*/
static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size)
{
/* expanded loop */
hash[ 0] ^= le2me_64(block[ 0]);
hash[ 1] ^= le2me_64(block[ 1]);
hash[ 2] ^= le2me_64(block[ 2]);
hash[ 3] ^= le2me_64(block[ 3]);
hash[ 4] ^= le2me_64(block[ 4]);
hash[ 5] ^= le2me_64(block[ 5]);
hash[ 6] ^= le2me_64(block[ 6]);
hash[ 7] ^= le2me_64(block[ 7]);
hash[ 8] ^= le2me_64(block[ 8]);
/* if not sha3-512 */
if (block_size > 72) {
hash[ 9] ^= le2me_64(block[ 9]);
hash[10] ^= le2me_64(block[10]);
hash[11] ^= le2me_64(block[11]);
hash[12] ^= le2me_64(block[12]);
/* if not sha3-384 */
if (block_size > 104) {
hash[13] ^= le2me_64(block[13]);
hash[14] ^= le2me_64(block[14]);
hash[15] ^= le2me_64(block[15]);
hash[16] ^= le2me_64(block[16]);
/* if not sha3-256 */
if (block_size > 136) {
hash[17] ^= le2me_64(block[17]);
#ifdef FULL_SHA3_FAMILY_SUPPORT
/* if not sha3-224 */
if (block_size > 144) {
hash[18] ^= le2me_64(block[18]);
hash[19] ^= le2me_64(block[19]);
hash[20] ^= le2me_64(block[20]);
hash[21] ^= le2me_64(block[21]);
hash[22] ^= le2me_64(block[22]);
hash[23] ^= le2me_64(block[23]);
hash[24] ^= le2me_64(block[24]);
}
#endif
}
}
}
/* make a permutation of the hash */
rhash_sha3_permutation(hash);
}
#define SHA3_FINALIZED 0x80000000
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size)
{
size_t index = (size_t)ctx->rest;
size_t block_size = (size_t)ctx->block_size;
if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */
ctx->rest = (unsigned)((ctx->rest + size) % block_size);
/* fill partial block */
if (index) {
size_t left = block_size - index;
memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
msg += left;
size -= left;
}
while (size >= block_size) {
uint64_t* aligned_message_block;
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (uint64_t*)msg;
} else {
memcpy(ctx->message, msg, block_size);
aligned_message_block = ctx->message;
}
rhash_sha3_process_block(ctx->hash, aligned_message_block, block_size);
msg += block_size;
size -= block_size;
}
if (size) {
memcpy(ctx->message, msg, size); /* save leftovers */
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result)
{
size_t digest_length = 100 - ctx->block_size / 2;
const size_t block_size = ctx->block_size;
if (!(ctx->rest & SHA3_FINALIZED))
{
/* clear the rest of the data queue */
memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
((char*)ctx->message)[ctx->rest] |= 0x06;
((char*)ctx->message)[block_size - 1] |= 0x80;
/* process final block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
}
assert(block_size > digest_length);
if (result) me64_to_le_str(result, ctx->hash, digest_length);
}
#ifdef USE_KECCAK
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result)
{
size_t digest_length = 100 - ctx->block_size / 2;
const size_t block_size = ctx->block_size;
if (!(ctx->rest & SHA3_FINALIZED))
{
/* clear the rest of the data queue */
memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
((char*)ctx->message)[ctx->rest] |= 0x01;
((char*)ctx->message)[block_size - 1] |= 0x80;
/* process final block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
}
assert(block_size > digest_length);
if (result) me64_to_le_str(result, ctx->hash, digest_length);
}
#endif /* USE_KECCAK */

View File

@ -0,0 +1,73 @@
/* sha3.h - an implementation of Secure Hash Algorithm 3 (Keccak).
* based on the
* The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
* by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
*
* Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
*/
#ifndef RHASH_SHA3_H
#define RHASH_SHA3_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define sha3_224_hash_size 28
#define sha3_256_hash_size 32
#define sha3_384_hash_size 48
#define sha3_512_hash_size 64
#define sha3_max_permutation_size 25
#define sha3_max_rate_in_qwords 24
/**
* SHA3 Algorithm context.
*/
typedef struct sha3_ctx
{
/* 1600 bits algorithm hashing state */
uint64_t hash[sha3_max_permutation_size];
/* 1536-bit buffer for leftovers */
uint64_t message[sha3_max_rate_in_qwords];
/* count of bytes in the message[] buffer */
unsigned rest;
/* size of a message block processed at once */
unsigned block_size;
} sha3_ctx;
/* methods for calculating the hash function */
void rhash_sha3_224_init(sha3_ctx *ctx);
void rhash_sha3_256_init(sha3_ctx *ctx);
void rhash_sha3_384_init(sha3_ctx *ctx);
void rhash_sha3_512_init(sha3_ctx *ctx);
void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size);
void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result);
#ifdef USE_KECCAK
#define rhash_keccak_224_init rhash_sha3_224_init
#define rhash_keccak_256_init rhash_sha3_256_init
#define rhash_keccak_384_init rhash_sha3_384_init
#define rhash_keccak_512_init rhash_sha3_512_init
#define rhash_keccak_update rhash_sha3_update
void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_SHA3_H */

View File

@ -0,0 +1,56 @@
import sys
sys.path.append('..')
sys.path.append('../lib')
import unittest
import trezor.utils
from trezor.crypto import hashlib
class TestCryptoSha3_256(unittest.TestCase):
# vectors from http://www.di-mgt.com.au/sha_testvectors.html
def test_digest(self):
self.assertEqual(hashlib.sha3_256(b'').digest(), trezor.utils.unhexlify('a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a'))
self.assertEqual(hashlib.sha3_256(b'abc').digest(), trezor.utils.unhexlify('3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532'))
self.assertEqual(hashlib.sha3_256(b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq').digest(), trezor.utils.unhexlify('41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376'))
self.assertEqual(hashlib.sha3_256(b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu').digest(), trezor.utils.unhexlify('916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18'))
def test_update(self):
x = hashlib.sha3_256()
self.assertEqual(x.digest(), trezor.utils.unhexlify('a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a'))
x = hashlib.sha3_256()
x.update(b'abc')
self.assertEqual(x.digest(), trezor.utils.unhexlify('3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532'))
x = hashlib.sha3_256()
x.update(b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
self.assertEqual(x.digest(), trezor.utils.unhexlify('41c0dba2a9d6240849100376a8235e2c82e1b9998a999e21db32dd97496d3376'))
x = hashlib.sha3_256()
x.update(b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu')
self.assertEqual(x.digest(), trezor.utils.unhexlify('916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18'))
x = hashlib.sha3_256()
for i in range(1000000):
x.update(b'a')
self.assertEqual(x.digest(), trezor.utils.unhexlify('5c8875ae474a3634ba4fd55ec85bffd661f32aca75c6d699d0cdcb6c115891c1'))
'''
x = hashlib.sha3_256()
for i in range(16777216):
x.update(b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno')
self.assertEqual(x.digest(), trezor.utils.unhexlify('ecbbc42cbf296603acb2c6bc0410ef4378bafb24b710357f12df607758b33e2b'))
'''
def test_digest_multi(self):
x = hashlib.sha3_256()
d0 = x.digest()
d1 = x.digest()
d2 = x.digest()
self.assertEqual(d0, d1)
self.assertEqual(d0, d2)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,56 @@
import sys
sys.path.append('..')
sys.path.append('../lib')
import unittest
import trezor.utils
from trezor.crypto import hashlib
class TestCryptoSha3_512(unittest.TestCase):
# vectors from http://www.di-mgt.com.au/sha_testvectors.html
def test_digest(self):
self.assertEqual(hashlib.sha3_512(b'').digest(), trezor.utils.unhexlify('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'))
self.assertEqual(hashlib.sha3_512(b'abc').digest(), trezor.utils.unhexlify('b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0'))
self.assertEqual(hashlib.sha3_512(b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq').digest(), trezor.utils.unhexlify('04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e'))
self.assertEqual(hashlib.sha3_512(b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu').digest(), trezor.utils.unhexlify('afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185'))
def test_update(self):
x = hashlib.sha3_512()
self.assertEqual(x.digest(), trezor.utils.unhexlify('a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26'))
x = hashlib.sha3_512()
x.update(b'abc')
self.assertEqual(x.digest(), trezor.utils.unhexlify('b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0'))
x = hashlib.sha3_512()
x.update(b'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq')
self.assertEqual(x.digest(), trezor.utils.unhexlify('04a371e84ecfb5b8b77cb48610fca8182dd457ce6f326a0fd3d7ec2f1e91636dee691fbe0c985302ba1b0d8dc78c086346b533b49c030d99a27daf1139d6e75e'))
x = hashlib.sha3_512()
x.update(b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu')
self.assertEqual(x.digest(), trezor.utils.unhexlify('afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185'))
x = hashlib.sha3_512()
for i in range(1000000):
x.update(b'a')
self.assertEqual(x.digest(), trezor.utils.unhexlify('3c3a876da14034ab60627c077bb98f7e120a2a5370212dffb3385a18d4f38859ed311d0a9d5141ce9cc5c66ee689b266a8aa18ace8282a0e0db596c90b0a7b87'))
'''
x = hashlib.sha3_512()
for i in range(16777216):
x.update(b'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno')
self.assertEqual(x.digest(), trezor.utils.unhexlify('235ffd53504ef836a1342b488f483b396eabbfe642cf78ee0d31feec788b23d0d18d5c339550dd5958a500d4b95363da1b5fa18affc1bab2292dc63b7d85097c'))
'''
def test_digest_multi(self):
x = hashlib.sha3_512()
d0 = x.digest()
d1 = x.digest()
d2 = x.digest()
self.assertEqual(d0, d1)
self.assertEqual(d0, d2)
if __name__ == '__main__':
unittest.main()

View File

@ -1,4 +1,6 @@
from TrezorCrypto import Ripemd160 as ripemd160 from TrezorCrypto import Ripemd160 as ripemd160
from TrezorCrypto import Sha256 as sha256 from TrezorCrypto import Sha256 as sha256
from TrezorCrypto import Sha512 as sha512 from TrezorCrypto import Sha512 as sha512
from TrezorCrypto import Sha3_256 as sha3_256
from TrezorCrypto import Sha3_512 as sha3_512
from TrezorCrypto import pbkdf2_hmac from TrezorCrypto import pbkdf2_hmac

2
vendor/micropython vendored

@ -1 +1 @@
Subproject commit ef0505fb5c70bf89a6d42d712bc54815e6024b36 Subproject commit f0ffa8c044759ba10bd092b3ad0e1434fa1b6654