format: start using clang-format with style=Google

pull/25/head
Pavol Rusnak 5 years ago
parent 8434b2468c
commit 0c622d62e1
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -0,0 +1,2 @@
---
BasedOnStyle: Google

@ -24,41 +24,41 @@
#include "address.h"
#include "bignum.h"
size_t address_prefix_bytes_len(uint32_t address_type)
{
size_t address_prefix_bytes_len(uint32_t address_type) {
if (address_type <= 0xFF) return 1;
if (address_type <= 0xFFFF) return 2;
if (address_type <= 0xFFFFFF) return 3;
return 4;
}
void address_write_prefix_bytes(uint32_t address_type, uint8_t *out)
{
void address_write_prefix_bytes(uint32_t address_type, uint8_t *out) {
if (address_type > 0xFFFFFF) *(out++) = address_type >> 24;
if (address_type > 0xFFFF) *(out++) = (address_type >> 16) & 0xFF;
if (address_type > 0xFF) *(out++) = (address_type >> 8) & 0xFF;
*(out++) = address_type & 0xFF;
}
bool address_check_prefix(const uint8_t *addr, uint32_t address_type)
{
bool address_check_prefix(const uint8_t *addr, uint32_t address_type) {
if (address_type <= 0xFF) {
return address_type == (uint32_t)(addr[0]);
}
if (address_type <= 0xFFFF) {
return address_type == (((uint32_t) addr[0] << 8) | ((uint32_t) addr[1]));
return address_type == (((uint32_t)addr[0] << 8) | ((uint32_t)addr[1]));
}
if (address_type <= 0xFFFFFF) {
return address_type == (((uint32_t) addr[0] << 16) | ((uint32_t) addr[1] << 8) | ((uint32_t) addr[2]));
return address_type == (((uint32_t)addr[0] << 16) |
((uint32_t)addr[1] << 8) | ((uint32_t)addr[2]));
}
return address_type == (((uint32_t) addr[0] << 24) | ((uint32_t) addr[1] << 16) | ((uint32_t) addr[2] << 8) | ((uint32_t) addr[3]));
return address_type ==
(((uint32_t)addr[0] << 24) | ((uint32_t)addr[1] << 16) |
((uint32_t)addr[2] << 8) | ((uint32_t)addr[3]));
}
#if USE_ETHEREUM
#include "sha3.h"
void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60, uint32_t chain_id)
{
void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60,
uint32_t chain_id) {
const char *hex = "0123456789abcdef";
for (int i = 0; i < 20; i++) {
address[i * 2] = hex[(addr[i] >> 4) & 0xF];
@ -71,17 +71,19 @@ void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60,
keccak_256_Init(&ctx);
if (rskip60) {
char prefix[16];
int prefix_size = bn_format_uint64(chain_id, NULL, "0x", 0, 0, false, prefix, sizeof(prefix));
int prefix_size = bn_format_uint64(chain_id, NULL, "0x", 0, 0, false,
prefix, sizeof(prefix));
keccak_Update(&ctx, (const uint8_t *)prefix, prefix_size);
}
keccak_Update(&ctx, (const uint8_t *)address, 40);
keccak_Final(&ctx, hash);
for (int i = 0; i < 20; i++) {
if (hash[i] & 0x80 && address[i * 2 ] >= 'a' && address[i * 2 ] <= 'f') {
if (hash[i] & 0x80 && address[i * 2] >= 'a' && address[i * 2] <= 'f') {
address[i * 2] -= 0x20;
}
if (hash[i] & 0x08 && address[i * 2 + 1] >= 'a' && address[i * 2 + 1] <= 'f') {
if (hash[i] & 0x08 && address[i * 2 + 1] >= 'a' &&
address[i * 2 + 1] <= 'f') {
address[i * 2 + 1] -= 0x20;
}
}

@ -24,16 +24,17 @@
#ifndef __ADDRESS_H__
#define __ADDRESS_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "options.h"
size_t address_prefix_bytes_len(uint32_t address_type);
void address_write_prefix_bytes(uint32_t address_type, uint8_t *out);
bool address_check_prefix(const uint8_t *addr, uint32_t address_type);
#if USE_ETHEREUM
void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60, uint32_t chain_id);
void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60,
uint32_t chain_id);
#endif
#endif

@ -27,19 +27,23 @@
const char *BASE32_ALPHABET_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789";
static inline void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out);
static inline bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, const char *alphabet);
static inline void base32_8to5_raw(const uint8_t *in, uint8_t length, uint8_t *out);
static inline bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out,
const char *alphabet);
static inline void base32_8to5_raw(const uint8_t *in, uint8_t length,
uint8_t *out);
static inline int base32_encode_character(uint8_t decoded, const char *alphabet);
static inline int base32_encode_character(uint8_t decoded,
const char *alphabet);
static inline int base32_decode_character(char encoded, const char *alphabet);
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet) {
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen,
const char *alphabet) {
size_t length = base32_encoded_length(inlen);
if (outlen <= length) {
return NULL;
}
base32_encode_unsafe(in, inlen, (uint8_t *) out);
base32_encode_unsafe(in, inlen, (uint8_t *)out);
for (size_t i = 0; i < length; i++) {
int ret = base32_encode_character(out[i], alphabet);
@ -55,13 +59,14 @@ char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, c
return &out[length];
}
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet) {
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out,
size_t outlen, const char *alphabet) {
size_t length = base32_decoded_length(inlen);
if (outlen < length) {
return NULL;
}
if (!base32_decode_unsafe((uint8_t *) in, inlen, (uint8_t *) out, alphabet)) {
if (!base32_decode_unsafe((uint8_t *)in, inlen, (uint8_t *)out, alphabet)) {
return NULL;
}
@ -80,7 +85,8 @@ void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out) {
if (remainder) base32_5to8(&in[i], remainder, &out[j]);
}
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet) {
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out,
const char *alphabet) {
uint8_t remainder = inlen % 8;
size_t limit = inlen - remainder;
@ -139,7 +145,8 @@ void base32_5to8(const uint8_t *in, uint8_t length, uint8_t *out) {
}
}
bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out, const char *alphabet) {
bool base32_8to5(const uint8_t *in, uint8_t length, uint8_t *out,
const char *alphabet) {
if (length == 1 || length == 3 || length == 6 || length > 8) {
return false;
}

@ -29,11 +29,14 @@
extern const char *BASE32_ALPHABET_RFC4648;
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen, const char *alphabet);
char *base32_encode(const uint8_t *in, size_t inlen, char *out, size_t outlen,
const char *alphabet);
void base32_encode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out);
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out, size_t outlen, const char *alphabet);
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out, const char *alphabet);
uint8_t *base32_decode(const char *in, size_t inlen, uint8_t *out,
size_t outlen, const char *alphabet);
bool base32_decode_unsafe(const uint8_t *in, size_t inlen, uint8_t *out,
const char *alphabet);
size_t base32_encoded_length(size_t inlen);
size_t base32_decoded_length(size_t inlen);

@ -21,35 +21,34 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include "base58.h"
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>
#include "base58.h"
#include "sha2.h"
#include "ripemd160.h"
#include "memzero.h"
#include "ripemd160.h"
#include "sha2.h"
const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
const char b58digits_ordered[] =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
const int8_t b58digits_map[] = {
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
-1, 9,10,11,12,13,14,15,16,-1,17,18,19,20,21,-1,
22,23,24,25,26,27,28,29,30,31,32,-1,-1,-1,-1,-1,
-1,33,34,35,36,37,38,39,40,41,42,43,-1,44,45,46,
47,48,49,50,51,52,53,54,55,56,57,-1,-1,-1,-1,-1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7,
8, -1, -1, -1, -1, -1, -1, -1, 9, 10, 11, 12, 13, 14, 15, 16, -1, 17, 18,
19, 20, 21, -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1,
-1, -1, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, -1, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, -1, -1, -1, -1, -1,
};
bool b58tobin(void *bin, size_t *binszp, const char *b58)
{
bool b58tobin(void *bin, size_t *binszp, const char *b58) {
size_t binsz = *binszp;
if (binsz == 0) {
return false;
}
const unsigned char *b58u = (const unsigned char*)b58;
const unsigned char *b58u = (const unsigned char *)b58;
unsigned char *binu = bin;
size_t outisz = (binsz + 3) / 4;
uint32_t outi[outisz];
@ -66,11 +65,9 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58)
memzero(outi, sizeof(outi));
// Leading zeros, just count
for (i = 0; i < b58sz && b58u[i] == '1'; ++i)
++zerocount;
for (i = 0; i < b58sz && b58u[i] == '1'; ++i) ++zerocount;
for ( ; i < b58sz; ++i)
{
for (; i < b58sz; ++i) {
if (b58u[i] & 0x80)
// High-bit set on invalid digit
return false;
@ -78,8 +75,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58)
// Invalid base58 digit
return false;
c = (unsigned)b58digits_map[b58u[i]];
for (j = outisz; j--; )
{
for (j = outisz; j--;) {
t = ((uint64_t)outi[j]) * 58 + c;
c = (t & 0x3f00000000) >> 32;
outi[j] = t & 0xffffffff;
@ -108,8 +104,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58)
break;
}
for (; j < outisz; ++j)
{
for (; j < outisz; ++j) {
*(binu++) = (outi[j] >> 0x18) & 0xff;
*(binu++) = (outi[j] >> 0x10) & 0xff;
*(binu++) = (outi[j] >> 8) & 0xff;
@ -118,8 +113,7 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58)
// Count canonical base58 byte count
binu = bin;
for (i = 0; i < binsz; ++i)
{
for (i = 0; i < binsz; ++i) {
if (binu[i]) {
if (zerocount > i) {
/* result too large */
@ -134,60 +128,53 @@ bool b58tobin(void *bin, size_t *binszp, const char *b58)
return true;
}
int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str)
{
int b58check(const void *bin, size_t binsz, HasherType hasher_type,
const char *base58str) {
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
if (binsz < 4) return -4;
hasher_Raw(hasher_type, bin, binsz - 4, buf);
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
if (memcmp(&binc[binsz - 4], buf, 4)) return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
// Check number of zeros is correct AFTER verifying checksum (to avoid
// possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) {
} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1') return -3;
return binc[0];
}
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
{
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz) {
const uint8_t *bin = data;
int carry;
ssize_t i, j, high, zcount = 0;
size_t size;
while (zcount < (ssize_t)binsz && !bin[zcount])
++zcount;
while (zcount < (ssize_t)binsz && !bin[zcount]) ++zcount;
size = (binsz - zcount) * 138 / 100 + 1;
uint8_t buf[size];
memzero(buf, size);
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j)
{
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
{
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) {
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
carry += 256 * buf[j];
buf[j] = carry % 58;
carry /= 58;
}
}
for (j = 0; j < (ssize_t)size && !buf[j]; ++j);
for (j = 0; j < (ssize_t)size && !buf[j]; ++j)
;
if (*b58sz <= zcount + size - j)
{
if (*b58sz <= zcount + size - j) {
*b58sz = zcount + size - j + 1;
return false;
}
if (zcount)
memset(b58, '1', zcount);
if (zcount) memset(b58, '1', zcount);
for (i = zcount; j < (ssize_t)size; ++i, ++j)
b58[i] = b58digits_ordered[buf[j]];
b58[i] = '\0';
@ -196,8 +183,8 @@ bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
return true;
}
int base58_encode_check(const uint8_t *data, int datalen, HasherType hasher_type, char *str, int strsize)
{
int base58_encode_check(const uint8_t *data, int datalen,
HasherType hasher_type, char *str, int strsize) {
if (datalen > 128) {
return 0;
}
@ -211,8 +198,8 @@ int base58_encode_check(const uint8_t *data, int datalen, HasherType hasher_type
return success ? res : 0;
}
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen)
{
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data,
int datalen) {
if (datalen > 128) {
return 0;
}
@ -230,28 +217,25 @@ int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data,
}
#if USE_GRAPHENE
int b58gphcheck(const void *bin, size_t binsz, const char *base58str)
{
int b58gphcheck(const void *bin, size_t binsz, const char *base58str) {
unsigned char buf[32];
const uint8_t *binc = bin;
unsigned i;
if (binsz < 4)
return -4;
if (binsz < 4) return -4;
ripemd160(bin, binsz - 4, buf); // No double SHA256, but a single RIPEMD160
if (memcmp(&binc[binsz - 4], buf, 4))
return -1;
if (memcmp(&binc[binsz - 4], buf, 4)) return -1;
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
{} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1')
return -3;
// Check number of zeros is correct AFTER verifying checksum (to avoid
// possibility of accessing base58str beyond the end)
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i) {
} // Just finding the end of zeros, nothing to do in loop
if (binc[i] == '\0' || base58str[i] == '1') return -3;
return binc[0];
}
int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize)
{
int base58gph_encode_check(const uint8_t *data, int datalen, char *str,
int strsize) {
if (datalen > 128) {
return 0;
}
@ -265,8 +249,7 @@ int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strs
return success ? res : 0;
}
int base58gph_decode_check(const char *str, uint8_t *data, int datalen)
{
int base58gph_decode_check(const char *str, uint8_t *data, int datalen) {
if (datalen > 128) {
return 0;
}

@ -24,24 +24,28 @@
#ifndef __BASE58_H__
#define __BASE58_H__
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>
#include "hasher.h"
#include "options.h"
extern const char b58digits_ordered[];
extern const int8_t b58digits_map[];
int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type, char *str, int strsize);
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data, int datalen);
int base58_encode_check(const uint8_t *data, int len, HasherType hasher_type,
char *str, int strsize);
int base58_decode_check(const char *str, HasherType hasher_type, uint8_t *data,
int datalen);
// Private
bool b58tobin(void *bin, size_t *binszp, const char *b58);
int b58check(const void *bin, size_t binsz, HasherType hasher_type, const char *base58str);
int b58check(const void *bin, size_t binsz, HasherType hasher_type,
const char *base58str);
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz);
#if USE_GRAPHENE
int base58gph_encode_check(const uint8_t *data, int datalen, char *str, int strsize);
int base58gph_encode_check(const uint8_t *data, int datalen, char *str,
int strsize);
int base58gph_decode_check(const char *str, uint8_t *data, int datalen);
int b58gphcheck(const void *bin, size_t binsz, const char *base58str);
#endif

@ -23,10 +23,10 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "bignum.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "bignum.h"
#include "memzero.h"
/* big number library */
@ -54,32 +54,24 @@
* 2^256 and it must be a prime number.
*/
inline uint32_t read_be(const uint8_t *data)
{
return (((uint32_t)data[0]) << 24) |
(((uint32_t)data[1]) << 16) |
(((uint32_t)data[2]) << 8) |
(((uint32_t)data[3]));
inline uint32_t read_be(const uint8_t *data) {
return (((uint32_t)data[0]) << 24) | (((uint32_t)data[1]) << 16) |
(((uint32_t)data[2]) << 8) | (((uint32_t)data[3]));
}
inline void write_be(uint8_t *data, uint32_t x)
{
inline void write_be(uint8_t *data, uint32_t x) {
data[0] = x >> 24;
data[1] = x >> 16;
data[2] = x >> 8;
data[3] = x;
}
inline uint32_t read_le(const uint8_t *data)
{
return (((uint32_t)data[3]) << 24) |
(((uint32_t)data[2]) << 16) |
(((uint32_t)data[1]) << 8) |
(((uint32_t)data[0]));
inline uint32_t read_le(const uint8_t *data) {
return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) |
(((uint32_t)data[1]) << 8) | (((uint32_t)data[0]));
}
inline void write_le(uint8_t *data, uint32_t x)
{
inline void write_le(uint8_t *data, uint32_t x) {
data[3] = x >> 24;
data[2] = x >> 16;
data[1] = x >> 8;
@ -88,8 +80,7 @@ inline void write_le(uint8_t *data, uint32_t x)
// convert a raw bigendian 256 bit value into a normalized bignum.
// out_number is partly reduced (since it fits in 256 bit).
void bn_read_be(const uint8_t *in_number, bignum256 *out_number)
{
void bn_read_be(const uint8_t *in_number, bignum256 *out_number) {
int i;
uint32_t temp = 0;
for (i = 0; i < 8; i++) {
@ -97,25 +88,24 @@ void bn_read_be(const uint8_t *in_number, bignum256 *out_number)
// get next limb = (in_number % 2^(32(i+1))) >> 32i
uint32_t limb = read_be(in_number + (7 - i) * 4);
// temp = (in_number % 2^(32(i+1))) << 30i
temp |= limb << (2*i);
temp |= limb << (2 * i);
// store 30 bits into val[i]
out_number->val[i]= temp & 0x3FFFFFFF;
out_number->val[i] = temp & 0x3FFFFFFF;
// prepare temp for next round
temp = limb >> (30 - 2*i);
temp = limb >> (30 - 2 * i);
}
out_number->val[8] = temp;
}
// convert a normalized bignum to a raw bigendian 256 bit number.
// in_number must be fully reduced.
void bn_write_be(const bignum256 *in_number, uint8_t *out_number)
{
void bn_write_be(const bignum256 *in_number, uint8_t *out_number) {
int i;
uint32_t temp = in_number->val[8];
for (i = 0; i < 8; i++) {
// invariant: temp = (in_number >> 30*(8-i))
uint32_t limb = in_number->val[7 - i];
temp = (temp << (16 + 2*i)) | (limb >> (14 - 2*i));
temp = (temp << (16 + 2 * i)) | (limb >> (14 - 2 * i));
write_be(out_number + i * 4, temp);
temp = limb;
}
@ -123,8 +113,7 @@ void bn_write_be(const bignum256 *in_number, uint8_t *out_number)
// convert a raw little endian 256 bit value into a normalized bignum.
// out_number is partly reduced (since it fits in 256 bit).
void bn_read_le(const uint8_t *in_number, bignum256 *out_number)
{
void bn_read_le(const uint8_t *in_number, bignum256 *out_number) {
int i;
uint32_t temp = 0;
for (i = 0; i < 8; i++) {
@ -132,32 +121,30 @@ void bn_read_le(const uint8_t *in_number, bignum256 *out_number)
// get next limb = (in_number % 2^(32(i+1))) >> 32i
uint32_t limb = read_le(in_number + i * 4);
// temp = (in_number % 2^(32(i+1))) << 30i
temp |= limb << (2*i);
temp |= limb << (2 * i);
// store 30 bits into val[i]
out_number->val[i]= temp & 0x3FFFFFFF;
out_number->val[i] = temp & 0x3FFFFFFF;
// prepare temp for next round
temp = limb >> (30 - 2*i);
temp = limb >> (30 - 2 * i);
}
out_number->val[8] = temp;
}
// convert a normalized bignum to a raw little endian 256 bit number.
// in_number must be fully reduced.
void bn_write_le(const bignum256 *in_number, uint8_t *out_number)
{
void bn_write_le(const bignum256 *in_number, uint8_t *out_number) {
int i;
uint32_t temp = in_number->val[8];
for (i = 0; i < 8; i++) {
// invariant: temp = (in_number >> 30*(8-i))
uint32_t limb = in_number->val[7 - i];
temp = (temp << (16 + 2*i)) | (limb >> (14 - 2*i));
temp = (temp << (16 + 2 * i)) | (limb >> (14 - 2 * i));
write_le(out_number + (7 - i) * 4, temp);
temp = limb;
}
}
void bn_read_uint32(uint32_t in_number, bignum256 *out_number)
{
void bn_read_uint32(uint32_t in_number, bignum256 *out_number) {
out_number->val[0] = in_number & 0x3FFFFFFF;
out_number->val[1] = in_number >> 30;
out_number->val[2] = 0;
@ -169,8 +156,7 @@ void bn_read_uint32(uint32_t in_number, bignum256 *out_number)
out_number->val[8] = 0;
}
void bn_read_uint64(uint64_t in_number, bignum256 *out_number)
{
void bn_read_uint64(uint64_t in_number, bignum256 *out_number) {
out_number->val[0] = in_number & 0x3FFFFFFF;
out_number->val[1] = (in_number >>= 30) & 0x3FFFFFFF;
out_number->val[2] = in_number >>= 30;
@ -183,8 +169,7 @@ void bn_read_uint64(uint64_t in_number, bignum256 *out_number)
}
// a must be normalized
int bn_bitcount(const bignum256 *a)
{
int bn_bitcount(const bignum256 *a) {
int i;
for (i = 8; i >= 0; i--) {
int tmp = a->val[i];
@ -197,8 +182,7 @@ int bn_bitcount(const bignum256 *a)
#define DIGITS 78 // log10(2 ^ 256)
unsigned int bn_digitcount(const bignum256 *a)
{
unsigned int bn_digitcount(const bignum256 *a) {
bignum256 val;
memcpy(&val, a, sizeof(bignum256));
@ -221,8 +205,7 @@ unsigned int bn_digitcount(const bignum256 *a)
}
// sets a bignum to zero.
void bn_zero(bignum256 *a)
{
void bn_zero(bignum256 *a) {
int i;
for (i = 0; i < 9; i++) {
a->val[i] = 0;
@ -230,8 +213,7 @@ void bn_zero(bignum256 *a)
}
// sets a bignum to one.
void bn_one(bignum256 *a)
{
void bn_one(bignum256 *a) {
a->val[0] = 1;
a->val[1] = 0;
a->val[2] = 0;
@ -246,8 +228,7 @@ void bn_one(bignum256 *a)
// checks that a bignum is zero.
// a must be normalized
// function is constant time (on some architectures, in particular ARM).
int bn_is_zero(const bignum256 *a)
{
int bn_is_zero(const bignum256 *a) {
int i;
uint32_t result = 0;
for (i = 0; i < 9; i++) {
@ -259,8 +240,7 @@ int bn_is_zero(const bignum256 *a)
// Check whether a < b
// a and b must be normalized
// function is constant time (on some architectures, in particular ARM).
int bn_is_less(const bignum256 *a, const bignum256 *b)
{
int bn_is_less(const bignum256 *a, const bignum256 *b) {
int i;
uint32_t res1 = 0;
uint32_t res2 = 0;
@ -286,34 +266,32 @@ int bn_is_equal(const bignum256 *a, const bignum256 *b) {
// Assigns res = cond ? truecase : falsecase
// assumes that cond is either 0 or 1.
// function is constant time.
void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase, const bignum256 *falsecase)
{
void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase,
const bignum256 *falsecase) {
int i;
uint32_t tmask = (uint32_t) -cond;
uint32_t tmask = (uint32_t)-cond;
uint32_t fmask = ~tmask;
assert (cond == 1 || cond == 0);
assert(cond == 1 || cond == 0);
for (i = 0; i < 9; i++) {
res->val[i] = (truecase->val[i] & tmask) |
(falsecase->val[i] & fmask);
res->val[i] = (truecase->val[i] & tmask) | (falsecase->val[i] & fmask);
}
}
// shift number to the left, i.e multiply it by 2.
// a must be normalized. The result is normalized but not reduced.
void bn_lshift(bignum256 *a)
{
void bn_lshift(bignum256 *a) {
int i;
for (i = 8; i > 0; i--) {
a->val[i] = ((a->val[i] << 1) & 0x3FFFFFFF) | ((a->val[i - 1] & 0x20000000) >> 29);
a->val[i] =
((a->val[i] << 1) & 0x3FFFFFFF) | ((a->val[i - 1] & 0x20000000) >> 29);
}
a->val[0] = (a->val[0] << 1) & 0x3FFFFFFF;
}
// shift number to the right, i.e divide by 2 while rounding down.
// a must be normalized. The result is normalized.
void bn_rshift(bignum256 *a)
{
void bn_rshift(bignum256 *a) {
int i;
for (i = 0; i < 8; i++) {
a->val[i] = (a->val[i] >> 1) | ((a->val[i + 1] & 1) << 29);
@ -322,26 +300,22 @@ void bn_rshift(bignum256 *a)
}
// sets bit in bignum
void bn_setbit(bignum256 *a, uint8_t bit)
{
void bn_setbit(bignum256 *a, uint8_t bit) {
a->val[bit / 30] |= (1u << (bit % 30));
}
// clears bit in bignum
void bn_clearbit(bignum256 *a, uint8_t bit)
{
void bn_clearbit(bignum256 *a, uint8_t bit) {
a->val[bit / 30] &= ~(1u << (bit % 30));
}
// tests bit in bignum
uint32_t bn_testbit(bignum256 *a, uint8_t bit)
{
uint32_t bn_testbit(bignum256 *a, uint8_t bit) {
return a->val[bit / 30] & (1u << (bit % 30));
}
// a = b ^ c
void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c)
{
void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c) {
int i;
for (i = 0; i < 9; i++) {
a->val[i] = b->val[i] ^ c->val[i];
@ -353,15 +327,14 @@ void bn_xor(bignum256 *a, const bignum256 *b, const bignum256 *c)
// assumes x is normalized.
// if x was partly reduced, it is also partly reduced on exit.
// function is constant time.
void bn_mult_half(bignum256 * x, const bignum256 *prime)
{
void bn_mult_half(bignum256 *x, const bignum256 *prime) {
int j;
uint32_t xodd = -(x->val[0] & 1);
// compute x = x/2 mod prime
// if x is odd compute (x+prime)/2
uint32_t tmp1 = (x->val[0] + (prime->val[0] & xodd)) >> 1;
for (j = 0; j < 8; j++) {
uint32_t tmp2 = (x->val[j+1] + (prime->val[j+1] & xodd));
uint32_t tmp2 = (x->val[j + 1] + (prime->val[j + 1] & xodd));
tmp1 += (tmp2 & 1) << 29;
x->val[j] = tmp1 & 0x3fffffff;
tmp1 >>= 30;
@ -373,8 +346,7 @@ void bn_mult_half(bignum256 * x, const bignum256 *prime)
// multiply x by k modulo prime.
// assumes x is normalized, 0 <= k <= 4.
// guarantees x is partly reduced.
void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime)
{
void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime) {
int j;
for (j = 0; j < 9; j++) {
x->val[j] = k * x->val[j];
@ -384,8 +356,7 @@ void bn_mult_k(bignum256 *x, uint8_t k, const bignum256 *prime)
// compute x = x mod prime by computing x >= prime ? x - prime : x.
// assumes x partly reduced, guarantees x fully reduced.
void bn_mod(bignum256 *x, const bignum256 *prime)
{
void bn_mod(bignum256 *x, const bignum256 *prime) {
const int flag = bn_is_less(x, prime); // x < prime
bignum256 temp;
bn_subtract(x, prime, &temp); // temp = x - prime
@ -395,14 +366,13 @@ void bn_mod(bignum256 *x, const bignum256 *prime)
// auxiliary function for multiplication.
// compute k * x as a 540 bit number in base 2^30 (normalized).
// assumes that k and x are normalized.
void bn_multiply_long(const bignum256 *k, const bignum256 *x, uint32_t res[18])
{
void bn_multiply_long(const bignum256 *k, const bignum256 *x,
uint32_t res[18]) {
int i, j;
uint64_t temp = 0;
// compute lower half of long multiplication
for (i = 0; i < 9; i++)
{
for (i = 0; i < 9; i++) {
for (j = 0; j <= i; j++) {
// no overflow, since 9*2^60 < 2^64
temp += k->val[j] * (uint64_t)x->val[i - j];
@ -411,9 +381,8 @@ void bn_multiply_long(const bignum256 *k, const bignum256 *x, uint32_t res[18])
temp >>= 30;
}
// compute upper half
for (; i < 17; i++)
{
for (j = i - 8; j < 9 ; j++) {
for (; i < 17; i++) {
for (j = i - 8; j < 9; j++) {
// no overflow, since 9*2^60 < 2^64
temp += k->val[j] * (uint64_t)x->val[i - j];
}
@ -428,7 +397,8 @@ void bn_multiply_long(const bignum256 *k, const bignum256 *x, uint32_t res[18])
// assumes i >= 8 and i <= 16
// assumes res normalized, res < 2^(30(i-7)) * 2 * prime
// guarantees res normalized, res < 2^(30(i-8)) * 2 * prime
void bn_multiply_reduce_step(uint32_t res[18], const bignum256 *prime, uint32_t i) {
void bn_multiply_reduce_step(uint32_t res[18], const bignum256 *prime,
uint32_t i) {
// let k = i-8.
// on entry:
// 0 <= res < 2^(30k + 31) * prime
@ -440,14 +410,16 @@ void bn_multiply_reduce_step(uint32_t res[18], const bignum256 *prime, uint32_t
assert(i >= 8 && i <= 16);
uint32_t j;
uint32_t coef = (res[i] >> 16) + (res[i + 1] << 14);
uint64_t temp = 0x2000000000000000ull + res[i - 8] - prime->val[0] * (uint64_t)coef;
assert (coef < 0x80000000u);
uint64_t temp =
0x2000000000000000ull + res[i - 8] - prime->val[0] * (uint64_t)coef;
assert(coef < 0x80000000u);
res[i - 8] = temp & 0x3FFFFFFF;
for (j = 1; j < 9; j++) {
temp >>= 30;
// Note: coeff * prime->val[j] <= (2^31-1) * (2^30-1)
// Hence, this addition will not underflow.
temp += 0x1FFFFFFF80000000ull + res[i - 8 + j] - prime->val[j] * (uint64_t)coef;
temp +=
0x1FFFFFFF80000000ull + res[i - 8 + j] - prime->val[j] * (uint64_t)coef;
res[i - 8 + j] = temp & 0x3FFFFFFF;
// 0 <= temp < 2^61 + 2^30
}
@ -463,13 +435,12 @@ void bn_multiply_reduce_step(uint32_t res[18], const bignum256 *prime, uint32_t
// < 2^30k (2 * prime)
}
// auxiliary function for multiplication.
// reduces x = res modulo prime.
// assumes res normalized, res < 2^270 * 2 * prime
// guarantees x partly reduced, i.e., x < 2 * prime
void bn_multiply_reduce(bignum256 *x, uint32_t res[18], const bignum256 *prime)
{
void bn_multiply_reduce(bignum256 *x, uint32_t res[18],
const bignum256 *prime) {
int i;
// res = k * x is a normalized number (every limb < 2^30)
// 0 <= res < 2^270 * 2 * prime.
@ -487,8 +458,7 @@ void bn_multiply_reduce(bignum256 *x, uint32_t res[18], const bignum256 *prime)
// both inputs must be smaller than 180 * prime.
// result is partly reduced (0 <= x < 2 * prime)
// This only works for primes between 2^256-2^224 and 2^256.
void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime)
{
void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime) {
uint32_t res[18] = {0};
bn_multiply_long(k, x, res);
bn_multiply_reduce(x, res, prime);
@ -500,8 +470,7 @@ void bn_multiply(const bignum256 *k, bignum256 *x, const bignum256 *prime)
// x can be any number that fits.
// prime must be between (2^256 - 2^224) and 2^256
// result is partly reduced, smaller than 2*prime
void bn_fast_mod(bignum256 *x, const bignum256 *prime)
{
void bn_fast_mod(bignum256 *x, const bignum256 *prime) {
int j;
uint32_t coef;
uint64_t temp;
@ -522,8 +491,7 @@ void bn_fast_mod(bignum256 *x, const bignum256 *prime)
// http://en.wikipedia.org/wiki/Quadratic_residue#Prime_or_prime_power_modulus
// assumes x is normalized but not necessarily reduced.
// guarantees x is reduced
void bn_sqrt(bignum256 *x, const bignum256 *prime)
{
void bn_sqrt(bignum256 *x, const bignum256 *prime) {
// this method compute x^1/2 = x^(prime+1)/4
uint32_t i, j, limb;
bignum256 res, p;
@ -558,11 +526,10 @@ void bn_sqrt(bignum256 *x, const bignum256 *prime)
memzero(&p, sizeof(p));
}
#if ! USE_INVERSE_FAST
#if !USE_INVERSE_FAST
// in field G_prime, small but slow
void bn_inverse(bignum256 *x, const bignum256 *prime)
{
void bn_inverse(bignum256 *x, const bignum256 *prime) {
// this method compute x^-1 = x^(prime-2)
uint32_t i, j, limb;
bignum256 res;
@ -573,7 +540,8 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// res = old(x)^((prime-2) % 2^(i*30))
// get the i-th limb of prime - 2
limb = prime->val[i];
// this is not enough in general but fine for secp256k1 & nist256p1 because prime->val[0] > 1
// this is not enough in general but fine for secp256k1 & nist256p1 because
// prime->val[0] > 1
if (i == 0) limb -= 2;
for (j = 0; j < 30; j++) {
// invariants:
@ -598,8 +566,7 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// in field G_prime, big and complicated but fast
// the input must not be 0 mod prime.
// the result is smaller than prime
void bn_inverse(bignum256 *x, const bignum256 *prime)
{
void bn_inverse(bignum256 *x, const bignum256 *prime) {
int i, j, k, cmp;
struct combo {
uint32_t a[9];
@ -624,15 +591,15 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// convert x and prime to 8x32 bit limb form
temp32 = prime->val[0];
for (i = 0; i < 8; i++) {
temp32 |= prime->val[i + 1] << (30-2*i);
temp32 |= prime->val[i + 1] << (30 - 2 * i);
us.a[i] = pp[i] = temp32;
temp32 = prime->val[i + 1] >> (2+2*i);
temp32 = prime->val[i + 1] >> (2 + 2 * i);
}
temp32 = x->val[0];
for (i = 0; i < 8; i++) {
temp32 |= x->val[i + 1] << (30-2*i);
temp32 |= x->val[i + 1] << (30 - 2 * i);
vr.a[i] = temp32;
temp32 = x->val[i + 1] >> (2+2*i);
temp32 = x->val[i + 1] >> (2 + 2 * i);
}
us.len1 = 8;
vr.len1 = 8;
@ -679,8 +646,7 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// if input was 0, return.
// This simple check prevents crashing with stack underflow
// or worse undesired behaviour for illegal input.
if (even->len1 < 0)
return;
if (even->len1 < 0) return;
}
// reduce even->a while it is even
@ -688,7 +654,7 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// shift right first part of even by a limb
// and shift left second part of even by a limb.
for (i = 0; i < 8; i++) {
even->a[i] = even->a[i+1];
even->a[i] = even->a[i + 1];
}
even->a[i] = 0;
even->len1--;
@ -733,8 +699,7 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
i = us.len1 - 1;
while (i >= 0 && us.a[i] == vr.a[i]) i--;
// both are equal to 1 and we are done.
if (i == -1)
break;
if (i == -1) break;
cmp = us.a[i] > vr.a[i] ? 1 : -1;
}
if (cmp > 0) {
@ -762,12 +727,12 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// odd->a[len1..8] = (odd->b[len1..8] + even->b[len1..8]);
temp = 0;
for (i = 8; i >= even->len1; i--) {
temp += (uint64_t) odd->a[i] + even->a[i];
temp += (uint64_t)odd->a[i] + even->a[i];
odd->a[i] = temp & 0xFFFFFFFF;
temp >>= 32;
}
for (; i >= odd->len1; i--) {
temp += (uint64_t) odd->a[i];
temp += (uint64_t)odd->a[i];
odd->a[i] = temp & 0xFFFFFFFF;
temp >>= 32;
}
@ -811,7 +776,7 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// zero mod 2^32 after at most five iterations.
// We want to compute -prime^-1 so we start with (pp[0]-2).
assert(pp[0] & 1);
uint32_t amone = pp[0]-1;
uint32_t amone = pp[0] - 1;
uint32_t inverse = pp[0] - 2;
while (amone) {
amone *= amone;
@ -825,15 +790,15 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// i.e. factor = s * -1/prime mod 2^32.
// Then compute s + factor*prime and shift right by 32 bits.
uint32_t factor = (inverse * us.a[8]) & 0xffffffff;
temp = us.a[8] + (uint64_t) pp[0] * factor;
temp = us.a[8] + (uint64_t)pp[0] * factor;
assert((temp & 0xffffffff) == 0);
temp >>= 32;
for (i = 0; i < 7; i++) {
temp += us.a[8-(i+1)] + (uint64_t) pp[i+1] * factor;
us.a[8-i] = temp & 0xffffffff;
temp += us.a[8 - (i + 1)] + (uint64_t)pp[i + 1] * factor;
us.a[8 - i] = temp & 0xffffffff;
temp >>= 32;
}
us.a[8-i] = temp & 0xffffffff;
us.a[8 - i] = temp & 0xffffffff;
k -= 32;
}
if (k > 0) {
@ -844,21 +809,21 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
// Then compute s + factor*prime and shift right by k bits.
uint32_t mask = (1u << k) - 1;
uint32_t factor = (inverse * us.a[8]) & mask;
temp = (us.a[8] + (uint64_t) pp[0] * factor) >> k;
temp = (us.a[8] + (uint64_t)pp[0] * factor) >> k;
assert(((us.a[8] + pp[0] * factor) & mask) == 0);
for (i = 0; i < 7; i++) {
temp += (us.a[8-(i+1)] + (uint64_t) pp[i+1] * factor) << (32 - k);
us.a[8-i] = temp & 0xffffffff;
temp += (us.a[8 - (i + 1)] + (uint64_t)pp[i + 1] * factor) << (32 - k);
us.a[8 - i] = temp & 0xffffffff;
temp >>= 32;
}
us.a[8-i] = temp & 0xffffffff;
us.a[8 - i] = temp & 0xffffffff;
}
// convert s to bignum style
temp32 = 0;
for (i = 0; i < 8; i++) {
x->val[i] = ((us.a[8-i] << (2 * i)) & 0x3FFFFFFFu) | temp32;
temp32 = us.a[8-i] >> (30 - 2 * i);
x->val[i] = ((us.a[8 - i] << (2 * i)) & 0x3FFFFFFFu) | temp32;
temp32 = us.a[8 - i] >> (30 - 2 * i);
}
x->val[i] = temp32;
@ -869,15 +834,12 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
}
#endif
void bn_normalize(bignum256 *a) {
bn_addi(a, 0);
}
void bn_normalize(bignum256 *a) { bn_addi(a, 0); }
// add two numbers a = a + b
// assumes that a, b are normalized
// guarantees that a is normalized
void bn_add(bignum256 *a, const bignum256 *b)
{
void bn_add(bignum256 *a, const bignum256 *b) {
int i;
uint32_t tmp = 0;
for (i = 0; i < 9; i++) {
@ -887,8 +849,7 @@ void bn_add(bignum256 *a, const bignum256 *b)
}
}
void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime)
{
void bn_addmod(bignum256 *a, const bignum256 *b, const bignum256 *prime) {
int i;
for (i = 0; i < 9; i++) {
a->val[i] += b->val[i];
@ -907,7 +868,7 @@ void bn_addi(bignum256 *a, uint32_t b) {
}
void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime) {
assert (b <= prime->val[0]);
assert(b <= prime->val[0]);
// the possible underflow will be taken care of when adding the prime
a->val[0] -= b;
bn_add(a, prime);
@ -916,8 +877,8 @@ void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime) {
// res = a - b mod prime. More exactly res = a + (2*prime - b).
// b must be a partly reduced number
// result is normalized but not reduced.
void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res, const bignum256 *prime)
{
void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res,
const bignum256 *prime) {
int i;
uint32_t temp = 1;
for (i = 0; i < 9; i++) {
@ -928,8 +889,7 @@ void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res, cons
}
// res = a - b ; a > b
void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res)
{
void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res) {
int i;
uint32_t tmp = 1;
for (i = 0; i < 9; i++) {
@ -940,8 +900,7 @@ void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res)
}
// a / 58 = a (+r)
void bn_divmod58(bignum256 *a, uint32_t *r)
{
void bn_divmod58(bignum256 *a, uint32_t *r) {
int i;
uint32_t rem, tmp;
rem = a->val[8] % 58;
@ -964,8 +923,7 @@ void bn_divmod58(bignum256 *a, uint32_t *r)
}
// a / 1000 = a (+r)
void bn_divmod1000(bignum256 *a, uint32_t *r)
{
void bn_divmod1000(bignum256 *a, uint32_t *r) {
int i;
uint32_t rem, tmp;
rem = a->val[8] % 1000;
@ -987,9 +945,11 @@ void bn_divmod1000(bignum256 *a, uint32_t *r)
*r = rem;
}
size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *out, size_t outlen)
{
// sanity check, 2**256 ~ 10**77; we should never need decimals/exponent bigger than that
size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix,
unsigned int decimals, int exponent, bool trailing, char *out,
size_t outlen) {
// sanity check, 2**256 ~ 10**77; we should never need decimals/exponent
// bigger than that
if (decimals > 80 || exponent < -20 || exponent > 80) {
memzero(out, outlen);
return 0;
@ -1087,8 +1047,7 @@ size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix,
}
#if USE_BN_PRINT
void bn_print(const bignum256 *a)
{
void bn_print(const bignum256 *a) {
printf("%04x", a->val[8] & 0x0000FFFF);
printf("%08x", (a->val[7] << 2) | ((a->val[6] & 0x30000000) >> 28));
printf("%07x", a->val[6] & 0x0FFFFFFF);
@ -1100,8 +1059,7 @@ void bn_print(const bignum256 *a)
printf("%07x", a->val[0] & 0x0FFFFFFF);
}
void bn_print_raw(const bignum256 *a)
{
void bn_print_raw(const bignum256 *a) {
int i;
for (i = 0; i <= 8; i++) {
printf("0x%08x, ", a->val[i]);

@ -60,13 +60,11 @@ void bn_read_uint32(uint32_t in_number, bignum256 *out_number);
void bn_read_uint64(uint64_t in_number, bignum256 *out_number);
static inline uint32_t bn_write_uint32(const bignum256 *in_number)
{
static inline uint32_t bn_write_uint32(const bignum256 *in_number) {
return in_number->val[0] | (in_number->val[1] << 30);
}
static inline uint64_t bn_write_uint64(const bignum256 *in_number)
{
static inline uint64_t bn_write_uint64(const bignum256 *in_number) {
uint64_t tmp;
tmp = in_number->val[2];
tmp <<= 30;
@ -77,9 +75,7 @@ static inline uint64_t bn_write_uint64(const bignum256 *in_number)
}
// copies number a to b
static inline void bn_copy(const bignum256 *a, bignum256 *b) {
*b = *a;
}
static inline void bn_copy(const bignum256 *a, bignum256 *b) { *b = *a; }
int bn_bitcount(const bignum256 *a);
@ -95,15 +91,14 @@ static inline int bn_is_even(const bignum256 *a) {
return (a->val[0] & 1) == 0;
}
static inline int bn_is_odd(const bignum256 *a) {
return (a->val[0] & 1) == 1;
}
static inline int bn_is_odd(const bignum256 *a) { return (a->val[0] & 1) == 1; }
int bn_is_less(const bignum256 *a, const bignum256 *b);
int bn_is_equal(const bignum256 *a, const bignum256 *b);
void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase, const bignum256 *falsecase);
void bn_cmov(bignum256 *res, int cond, const bignum256 *truecase,
const bignum256 *falsecase);
void bn_lshift(bignum256 *a);
@ -141,7 +136,8 @@ void bn_addi(bignum256 *a, uint32_t b);
void bn_subi(bignum256 *a, uint32_t b, const bignum256 *prime);
void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res, const bignum256 *prime);
void bn_subtractmod(const bignum256 *a, const bignum256 *b, bignum256 *res,
const bignum256 *prime);
void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res);
@ -149,14 +145,19 @@ void bn_divmod58(bignum256 *a, uint32_t *r);
void bn_divmod1000(bignum256 *a, uint32_t *r);
size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *out, size_t outlen);
size_t bn_format(const bignum256 *amnt, const char *prefix, const char *suffix,
unsigned int decimals, int exponent, bool trailing, char *out,
size_t outlen);
static inline size_t bn_format_uint64(uint64_t amount, const char *prefix, const char *suffix, unsigned int decimals, int exponent, bool trailing, char *out, size_t outlen)
{
static inline size_t bn_format_uint64(uint64_t amount, const char *prefix,
const char *suffix, unsigned int decimals,
int exponent, bool trailing, char *out,
size_t outlen) {
bignum256 amnt;
bn_read_uint64(amount, &amnt);
return bn_format(&amnt, prefix, suffix, decimals, exponent, trailing, out, outlen);
return bn_format(&amnt, prefix, suffix, decimals, exponent, trailing, out,
outlen);
}
#if USE_BN_PRINT

@ -22,23 +22,23 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <stdbool.h>
#include <string.h>
#include "aes/aes.h"
#include "address.h"
#include "aes/aes.h"
#include "base58.h"
#include "bignum.h"
#include "hmac.h"
#include "ecdsa.h"
#include "bip32.h"
#include "sha2.h"
#include "sha3.h"
#include "base58.h"
#include "curves.h"
#include "secp256k1.h"
#include "nist256p1.h"
#include "ed25519-donna/ed25519.h"
#include "ecdsa.h"
#include "ed25519-donna/ed25519-sha3.h"
#include "ed25519-donna/ed25519.h"
#include "hmac.h"
#include "nist256p1.h"
#include "secp256k1.h"
#include "sha2.h"
#include "sha3.h"
#if USE_KECCAK
#include "ed25519-donna/ed25519-keccak.h"
#endif
@ -97,8 +97,9 @@ const curve_info curve25519_info = {
.hasher_script = HASHER_SHA2,
};
int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char* curve, HDNode *out)
{
int hdnode_from_xpub(uint32_t depth, uint32_t child_num,
const uint8_t *chain_code, const uint8_t *public_key,
const char *curve, HDNode *out) {
const curve_info *info = get_curve_by_name(curve);
if (info == 0) {
return 0;
@ -111,13 +112,14 @@ int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_co
out->child_num = child_num;
memcpy(out->chain_code, chain_code, 32);
memzero(out->private_key, 32);
memzero(out->private_key_extension,32);
memzero(out->private_key_extension, 32);
memcpy(out->public_key, public_key, 33);
return 1;
}
int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char* curve, HDNode *out)
{
int hdnode_from_xprv(uint32_t depth, uint32_t child_num,
const uint8_t *chain_code, const uint8_t *private_key,
const char *curve, HDNode *out) {
bool failed = false;
const curve_info *info = get_curve_by_name(curve);
if (info == 0) {
@ -149,8 +151,8 @@ int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_co
return 1;
}
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNode *out)
{
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve,
HDNode *out) {
static CONFIDENTIAL uint8_t I[32 + 32];
memzero(out, sizeof(HDNode));
out->depth = 0;
@ -160,7 +162,8 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNod
return 0;
}
static CONFIDENTIAL HMAC_SHA512_CTX ctx;
hmac_sha512_Init(&ctx, (const uint8_t*) out->curve->bip32_name, strlen(out->curve->bip32_name));
hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name,
strlen(out->curve->bip32_name));
hmac_sha512_Update(&ctx, seed, seed_len);
hmac_sha512_Final(&ctx, I);
@ -172,7 +175,8 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNod
&& bn_is_less(&a, &out->curve->params->order)) { // < order
break;
}
hmac_sha512_Init(&ctx, (const uint8_t*) out->curve->bip32_name, strlen(out->curve->bip32_name));
hmac_sha512_Init(&ctx, (const uint8_t *)out->curve->bip32_name,
strlen(out->curve->bip32_name));
hmac_sha512_Update(&ctx, I, sizeof(I));
hmac_sha512_Final(&ctx, I);
}
@ -185,20 +189,19 @@ int hdnode_from_seed(const uint8_t *seed, int seed_len, const char* curve, HDNod
return 1;
}
uint32_t hdnode_fingerprint(HDNode *node)
{
uint32_t hdnode_fingerprint(HDNode *node) {
uint8_t digest[32];
uint32_t fingerprint;
hdnode_fill_public_key(node);
hasher_Raw(node->curve->hasher_pubkey, node->public_key, 33, digest);
fingerprint = ((uint32_t) digest[0] << 24) + (digest[1] << 16) + (digest[2] << 8) + digest[3];
fingerprint = ((uint32_t)digest[0] << 24) + (digest[1] << 16) +
(digest[2] << 8) + digest[3];
memzero(digest, sizeof(digest));
return fingerprint;
}
int hdnode_private_ckd(HDNode *inout, uint32_t i)
{
int hdnode_private_ckd(HDNode *inout, uint32_t i) {
static CONFIDENTIAL uint8_t data[1 + 32 + 4];
static CONFIDENTIAL uint8_t I[32 + 32];
static CONFIDENTIAL bignum256 a, b;
@ -265,8 +268,7 @@ int hdnode_private_ckd(HDNode *inout, uint32_t i)
}
#if USE_CARDANO
static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst)
{
static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst) {
uint8_t prev_acc = 0;
for (int i = 0; i < bytes; i++) {
dst[i] = (src[i] << 3) + (prev_acc & 0x7);
@ -275,8 +277,8 @@ static void scalar_multiply8(const uint8_t *src, int bytes, uint8_t *dst)
dst[bytes] = src[bytes - 1] >> 5;
}
static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2, uint8_t *dst)
{
static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2,
uint8_t *dst) {
uint16_t r = 0;
for (int i = 0; i < 32; i++) {
r = r + (uint16_t)src1[i] + (uint16_t)src2[i];
@ -285,9 +287,9 @@ static void scalar_add_256bits(const uint8_t *src1, const uint8_t *src2, uint8_t
}
}
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index)
{
// checks for hardened/non-hardened derivation, keysize 32 means we are dealing with public key and thus non-h, keysize 64 is for private key
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index) {
// checks for hardened/non-hardened derivation, keysize 32 means we are
// dealing with public key and thus non-h, keysize 64 is for private key
int keysize = 32;
if (index & 0x80000000) {
keysize = 64;
@ -354,7 +356,8 @@ int hdnode_private_ckd_cardano(HDNode *inout, uint32_t index)
return 1;
}
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len, const uint8_t *seed, int seed_len, HDNode *out) {
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len,
const uint8_t *seed, int seed_len, HDNode *out) {
static CONFIDENTIAL uint8_t secret[96];
pbkdf2_hmac_sha512(pass, pass_len, seed, seed_len, 4096, secret, 96);
@ -380,7 +383,9 @@ int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len, const uint8_t *s
}
#endif
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, const uint8_t *parent_chain_code, uint32_t i, curve_point *child, uint8_t *child_chain_code) {
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
const uint8_t *parent_chain_code, uint32_t i,
curve_point *child, uint8_t *child_chain_code) {
uint8_t data[1 + 32 + 4];
uint8_t I[32 + 32];
bignum256 c;
@ -417,14 +422,14 @@ int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, co
}
}
int hdnode_public_ckd(HDNode *inout, uint32_t i)
{
int hdnode_public_ckd(HDNode *inout, uint32_t i) {
curve_point parent, child;
if (!ecdsa_read_pubkey(inout->curve->params, inout->public_key, &parent)) {
return 0;
}
if (!hdnode_public_ckd_cp(inout->curve->params, &parent, inout->chain_code, i, &child, inout->chain_code)) {
if (!hdnode_public_ckd_cp(inout->curve->params, &parent, inout->chain_code, i,
&child, inout->chain_code)) {
return 0;
}
memzero(inout->private_key, 32);
@ -440,8 +445,12 @@ int hdnode_public_ckd(HDNode *inout, uint32_t i)
return 1;
}
void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *chain_code, uint32_t i, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize, int addrformat)
{
void hdnode_public_ckd_address_optimized(const curve_point *pub,
const uint8_t *chain_code, uint32_t i,
uint32_t version,
HasherType hasher_pubkey,
HasherType hasher_base58, char *addr,
int addrsize, int addrformat) {
uint8_t child_pubkey[33];
curve_point b;
@ -451,10 +460,12 @@ void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *
switch (addrformat) {
case 1: // Segwit-in-P2SH
ecdsa_get_address_segwit_p2sh(child_pubkey, version, hasher_pubkey, hasher_base58, addr, addrsize);
ecdsa_get_address_segwit_p2sh(child_pubkey, version, hasher_pubkey,
hasher_base58, addr, addrsize);
break;
default: // normal address
ecdsa_get_address(child_pubkey, version, hasher_pubkey, hasher_base58, addr, addrsize);
ecdsa_get_address(child_pubkey, version, hasher_pubkey, hasher_base58,
addr, addrsize);
break;
}
}
@ -471,8 +482,8 @@ static CONFIDENTIAL struct {
HDNode node;
} private_ckd_cache[BIP32_CACHE_SIZE];
int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, uint32_t *fingerprint)
{
int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
uint32_t *fingerprint) {
if (i_count == 0) {
// no way how to compute parent fingerprint
return 1;
@ -487,7 +498,8 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
bool found = false;
// if root is not set or not the same
if (!private_ckd_cache_root_set || memcmp(&private_ckd_cache_root, inout, sizeof(HDNode)) != 0) {
if (!private_ckd_cache_root_set ||
memcmp(&private_ckd_cache_root, inout, sizeof(HDNode)) != 0) {
// clear the cache
private_ckd_cache_index = 0;
memzero(private_ckd_cache, sizeof(private_ckd_cache));
@ -500,7 +512,8 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
for (j = 0; j < BIP32_CACHE_SIZE; j++) {
if (private_ckd_cache[j].set &&
private_ckd_cache[j].depth == i_count - 1 &&
memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) == 0 &&
memcmp(private_ckd_cache[j].i, i, (i_count - 1) * sizeof(uint32_t)) ==
0 &&
private_ckd_cache[j].node.curve == inout->curve) {
memcpy(inout, &(private_ckd_cache[j].node), sizeof(HDNode));
found = true;
@ -516,11 +529,14 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
if (hdnode_private_ckd(inout, i[k]) == 0) return 0;
}
// and save it
memzero(&(private_ckd_cache[private_ckd_cache_index]), sizeof(private_ckd_cache[private_ckd_cache_index]));
memzero(&(private_ckd_cache[private_ckd_cache_index]),
sizeof(private_ckd_cache[private_ckd_cache_index]));
private_ckd_cache[private_ckd_cache_index].set = true;
private_ckd_cache[private_ckd_cache_index].depth = i_count - 1;
memcpy(private_ckd_cache[private_ckd_cache_index].i, i, (i_count - 1) * sizeof(uint32_t));
memcpy(&(private_ckd_cache[private_ckd_cache_index].node), inout, sizeof(HDNode));
memcpy(private_ckd_cache[private_ckd_cache_index].i, i,
(i_count - 1) * sizeof(uint32_t));
memcpy(&(private_ckd_cache[private_ckd_cache_index].node), inout,
sizeof(HDNode));
private_ckd_cache_index = (private_ckd_cache_index + 1) % BIP32_CACHE_SIZE;
}
@ -533,26 +549,26 @@ int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
}
#endif
void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw)
{
void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw) {
hdnode_fill_public_key(node);
ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_pubkey, addr_raw);
ecdsa_get_address_raw(node->public_key, version, node->curve->hasher_pubkey,
addr_raw);
}
void hdnode_get_address(HDNode *node, uint32_t version, char *addr, int addrsize)
{
void hdnode_get_address(HDNode *node, uint32_t version, char *addr,
int addrsize) {
hdnode_fill_public_key(node);
ecdsa_get_address(node->public_key, version, node->curve->hasher_pubkey, node->curve->hasher_base58, addr, addrsize);
ecdsa_get_address(node->public_key, version, node->curve->hasher_pubkey,
node->curve->hasher_base58, addr, addrsize);
}
void hdnode_fill_public_key(HDNode *node)
{
if (node->public_key[0] != 0)
return;
void hdnode_fill_public_key(HDNode *node) {
if (node->public_key[0] != 0) return;
#if USE_BIP32_25519_CURVES
if (node->curve->params) {
ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key);
ecdsa_get_public_key33(node->curve->params, node->private_key,
node->public_key);
} else {
node->public_key[0] = 1;
if (node->curve == &ed25519_info) {
@ -567,19 +583,20 @@ void hdnode_fill_public_key(HDNode *node)
curve25519_scalarmult_basepoint(node->public_key + 1, node->private_key);
#if USE_CARDANO
} else if (node->curve == &ed25519_cardano_info) {
ed25519_publickey_ext(node->private_key, node->private_key_extension, node->public_key + 1);
ed25519_publickey_ext(node->private_key, node->private_key_extension,
node->public_key + 1);
#endif
}
}
#else
ecdsa_get_public_key33(node->curve->params, node->private_key, node->public_key);
ecdsa_get_public_key33(node->curve->params, node->private_key,
node->public_key);
#endif
}
#if USE_ETHEREUM
int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash)
{
int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash) {
uint8_t buf[65];
SHA3_CTX ctx;
@ -608,7 +625,10 @@ int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address) {
return nem_get_address(&node->public_key[1], version, address);
}
int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key) {
int hdnode_get_nem_shared_key(const HDNode *node,
const ed25519_public_key peer_public_key,
const uint8_t *salt, ed25519_public_key mul,
uint8_t *shared_key) {
if (node->curve != &ed25519_keccak_info) {
return 0;
}
@ -628,7 +648,9 @@ int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_
return 1;
}
int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key, const uint8_t *iv_immut, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer) {
int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key,
const uint8_t *iv_immut, const uint8_t *salt,
const uint8_t *payload, size_t size, uint8_t *buffer) {
uint8_t last_block[AES_BLOCK_SIZE];
uint8_t remainder = size % AES_BLOCK_SIZE;
@ -637,7 +659,8 @@ int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key,
// Copy old last block
memcpy(last_block, &payload[size], remainder);
// Pad new last block with number of missing bytes
memset(&last_block[remainder], AES_BLOCK_SIZE - remainder, AES_BLOCK_SIZE - remainder);
memset(&last_block[remainder], AES_BLOCK_SIZE - remainder,
AES_BLOCK_SIZE - remainder);
// the IV gets mutated, so we make a copy not to touch the original
uint8_t iv[AES_BLOCK_SIZE];
@ -661,14 +684,17 @@ int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key,
return 0;
}
if (aes_cbc_encrypt(last_block, &buffer[size], sizeof(last_block), iv, &ctx) != EXIT_SUCCESS) {
if (aes_cbc_encrypt(last_block, &buffer[size], sizeof(last_block), iv,
&ctx) != EXIT_SUCCESS) {
return 0;
}
return 1;
}
int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer) {
int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key,
uint8_t *iv, const uint8_t *salt, const uint8_t *payload,
size_t size, uint8_t *buffer) {
uint8_t shared_key[SHA3_256_DIGEST_LENGTH];
if (!hdnode_get_nem_shared_key(node, public_key, salt, NULL, shared_key)) {
@ -694,10 +720,12 @@ int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key,
// msg is a data to be signed
// msg_len is the message length
int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, HasherType hasher_sign, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]))
{
int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len,
HasherType hasher_sign, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
if (node->curve->params) {
return ecdsa_sign(node->curve->params, hasher_sign, node->private_key, msg, msg_len, sig, pby, is_canonical);
return ecdsa_sign(node->curve->params, hasher_sign, node->private_key, msg,
msg_len, sig, pby, is_canonical);
} else if (node->curve == &curve25519_info) {
return 1; // signatures are not supported
} else {
@ -705,20 +733,24 @@ int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, HasherType h
if (node->curve == &ed25519_info) {
ed25519_sign(msg, msg_len, node->private_key, node->public_key + 1, sig);
} else if (node->curve == &ed25519_sha3_info) {
ed25519_sign_sha3(msg, msg_len, node->private_key, node->public_key + 1, sig);
ed25519_sign_sha3(msg, msg_len, node->private_key, node->public_key + 1,
sig);
#if USE_KECCAK
} else if (node->curve == &ed25519_keccak_info) {
ed25519_sign_keccak(msg, msg_len, node->private_key, node->public_key + 1, sig);
ed25519_sign_keccak(msg, msg_len, node->private_key, node->public_key + 1,
sig);
#endif
}
return 0;
}
}
int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]))
{
int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig,
uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
if (node->curve->params) {
return ecdsa_sign_digest(node->curve->params, node->private_key, digest, sig, pby, is_canonical);
return ecdsa_sign_digest(node->curve->params, node->private_key, digest,
sig, pby, is_canonical);
} else if (node->curve == &curve25519_info) {
return 1; // signatures are not supported
} else {
@ -726,11 +758,12 @@ int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_
}
}
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size)
{
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key,
uint8_t *session_key, int *result_size) {
// Use elliptic curve Diffie-Helman to compute shared session key
if (node->curve->params) {
if (ecdh_multiply(node->curve->params, node->private_key, peer_public_key, session_key) != 0) {
if (ecdh_multiply(node->curve->params, node->private_key, peer_public_key,
session_key) != 0) {
return 1;
}
*result_size = 65;
@ -740,7 +773,8 @@ int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, ui
if (peer_public_key[0] != 0x40) {
return 1; // Curve25519 public key should start with 0x40 byte.
}
curve25519_scalarmult(session_key + 1, node->private_key, peer_public_key + 1);
curve25519_scalarmult(session_key + 1, node->private_key,
peer_public_key + 1);
*result_size = 33;
return 0;
} else {
@ -749,8 +783,9 @@ int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, ui
}
}
static int hdnode_serialize(const HDNode *node, uint32_t fingerprint, uint32_t version, char use_public, char *str, int strsize)
{
static int hdnode_serialize(const HDNode *node, uint32_t fingerprint,
uint32_t version, char use_public, char *str,
int strsize) {
uint8_t node_data[78];
write_be(node_data, version);
node_data[4] = node->depth;
@ -763,28 +798,31 @@ static int hdnode_serialize(const HDNode *node, uint32_t fingerprint, uint32_t v
node_data[45] = 0;
memcpy(node_data + 46, node->private_key, 32);
}
int ret = base58_encode_check(node_data, sizeof(node_data), node->curve->hasher_base58, str, strsize);
int ret = base58_encode_check(node_data, sizeof(node_data),
node->curve->hasher_base58, str, strsize);
memzero(node_data, sizeof(node_data));
return ret;
}
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize)
{
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint,
uint32_t version, char *str, int strsize) {
return hdnode_serialize(node, fingerprint, version, 1, str, strsize);
}
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize)
{
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint,
uint32_t version, char *str, int strsize) {
return hdnode_serialize(node, fingerprint, version, 0, str, strsize);
}
// check for validity of curve point in case of public data not performed
int hdnode_deserialize(const char *str, uint32_t version_public, uint32_t version_private, const char *curve, HDNode *node, uint32_t *fingerprint)
{
int hdnode_deserialize(const char *str, uint32_t version_public,
uint32_t version_private, const char *curve,
HDNode *node, uint32_t *fingerprint) {
uint8_t node_data[78];
memzero(node, sizeof(HDNode));
node->curve = get_curve_by_name(curve);
if (base58_decode_check(str, node->curve->hasher_base58, node_data, sizeof(node_data)) != sizeof(node_data)) {
if (base58_decode_check(str, node->curve->hasher_base58, node_data,
sizeof(node_data)) != sizeof(node_data)) {
return -1;
}
uint32_t version = read_be(node_data);

@ -24,9 +24,9 @@
#ifndef __BIP32_H__
#define __BIP32_H__
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include "ecdsa.h"
#include "ed25519-donna/ed25519.h"
#include "options.h"
@ -53,29 +53,44 @@ typedef struct {
const curve_info *curve;
} HDNode;
int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *public_key, const char *curve, HDNode *out);
int hdnode_from_xpub(uint32_t depth, uint32_t child_num,
const uint8_t *chain_code, const uint8_t *public_key,
const char *curve, HDNode *out);
int hdnode_from_xprv(uint32_t depth, uint32_t child_num, const uint8_t *chain_code, const uint8_t *private_key, const char *curve, HDNode *out);
int hdnode_from_xprv(uint32_t depth, uint32_t child_num,
const uint8_t *chain_code, const uint8_t *private_key,
const char *curve, HDNode *out);
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve, HDNode *out);
int hdnode_from_seed(const uint8_t *seed, int seed_len, const char *curve,
HDNode *out);
#define hdnode_private_ckd_prime(X, I) hdnode_private_ckd((X), ((I) | 0x80000000))
#define hdnode_private_ckd_prime(X, I) \
hdnode_private_ckd((X), ((I) | 0x80000000))
int hdnode_private_ckd(HDNode *inout, uint32_t i);
#if USE_CARDANO
int hdnode_private_ckd_cardano(HDNode *inout, uint32_t i);
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len, const uint8_t *seed, int seed_len, HDNode *out);
int hdnode_from_seed_cardano(const uint8_t *pass, int pass_len,
const uint8_t *seed, int seed_len, HDNode *out);
#endif
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent, const uint8_t *parent_chain_code, uint32_t i, curve_point *child, uint8_t *child_chain_code);
int hdnode_public_ckd_cp(const ecdsa_curve *curve, const curve_point *parent,
const uint8_t *parent_chain_code, uint32_t i,
curve_point *child, uint8_t *child_chain_code);
int hdnode_public_ckd(HDNode *inout, uint32_t i);
void hdnode_public_ckd_address_optimized(const curve_point *pub, const uint8_t *chain_code, uint32_t i, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize, int addrformat);
void hdnode_public_ckd_address_optimized(const curve_point *pub,
const uint8_t *chain_code, uint32_t i,
uint32_t version,
HasherType hasher_pubkey,
HasherType hasher_base58, char *addr,
int addrsize, int addrformat);
#if USE_BIP32_CACHE
int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count, uint32_t *fingerprint);
int hdnode_private_ckd_cached(HDNode *inout, const uint32_t *i, size_t i_count,
uint32_t *fingerprint);
#endif
uint32_t hdnode_fingerprint(HDNode *node);
@ -88,24 +103,41 @@ int hdnode_get_ethereum_pubkeyhash(const HDNode *node, uint8_t *pubkeyhash);
#if USE_NEM
int hdnode_get_nem_address(HDNode *node, uint8_t version, char *address);
int hdnode_get_nem_shared_key(const HDNode *node, const ed25519_public_key peer_public_key, const uint8_t *salt, ed25519_public_key mul, uint8_t *shared_key);
int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key, const uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer);
int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key, uint8_t *iv, const uint8_t *salt, const uint8_t *payload, size_t size, uint8_t *buffer);
int hdnode_get_nem_shared_key(const HDNode *node,
const ed25519_public_key peer_public_key,
const uint8_t *salt, ed25519_public_key mul,
uint8_t *shared_key);
int hdnode_nem_encrypt(const HDNode *node, const ed25519_public_key public_key,
const uint8_t *iv, const uint8_t *salt,
const uint8_t *payload, size_t size, uint8_t *buffer);
int hdnode_nem_decrypt(const HDNode *node, const ed25519_public_key public_key,
uint8_t *iv, const uint8_t *salt, const uint8_t *payload,
size_t size, uint8_t *buffer);
#endif
int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len, HasherType hasher_sign, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int hdnode_sign(HDNode *node, const uint8_t *msg, uint32_t msg_len,
HasherType hasher_sign, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int hdnode_sign_digest(HDNode *node, const uint8_t *digest, uint8_t *sig,
uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key, uint8_t *session_key, int *result_size);
int hdnode_get_shared_key(const HDNode *node, const uint8_t *peer_public_key,
uint8_t *session_key, int *result_size);
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize);
int hdnode_serialize_public(const HDNode *node, uint32_t fingerprint,
uint32_t version, char *str, int strsize);
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint, uint32_t version, char *str, int strsize);
int hdnode_serialize_private(const HDNode *node, uint32_t fingerprint,
uint32_t version, char *str, int strsize);
int hdnode_deserialize(const char *str, uint32_t version_public, uint32_t version_private, const char *curve, HDNode *node, uint32_t *fingerprint);
int hdnode_deserialize(const char *str, uint32_t version_public,
uint32_t version_private, const char *curve,
HDNode *node, uint32_t *fingerprint);
void hdnode_get_address_raw(HDNode *node, uint32_t version, uint8_t *addr_raw);
void hdnode_get_address(HDNode *node, uint32_t version, char *addr, int addrsize);
void hdnode_get_address(HDNode *node, uint32_t version, char *addr,
int addrsize);
const curve_info *get_curve_by_name(const char *curve_name);

@ -21,17 +21,17 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <stdbool.h>
#include <string.h>
#include "bip39.h"
#include "bip39_english.h"
#include "hmac.h"
#include "memzero.h"
#include "options.h"
#include "pbkdf2.h"
#include "rand.h"
#include "sha2.h"
#include "pbkdf2.h"
#include "bip39_english.h"
#include "options.h"
#include "memzero.h"
#if USE_BIP39_CACHE
@ -46,8 +46,7 @@ static CONFIDENTIAL struct {
#endif
const char *mnemonic_generate(int strength)
{
const char *mnemonic_generate(int strength) {
if (strength % 32 || strength < 128 || strength > 256) {
return 0;
}
@ -60,8 +59,7 @@ const char *mnemonic_generate(int strength)
static CONFIDENTIAL char mnemo[24 * 10];
const char *mnemonic_from_data(const uint8_t *data, int len)
{
const char *mnemonic_from_data(const uint8_t *data, int len) {
if (len % 4 || len < 16 || len > 32) {
return 0;
}
@ -94,13 +92,9 @@ const char *mnemonic_from_data(const uint8_t *data, int len)
return mnemo;
}
void mnemonic_clear(void)
{
memzero(mnemo, sizeof(mnemo));
}
void mnemonic_clear(void) { memzero(mnemo, sizeof(mnemo)); }
int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy)
{
int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy) {
if (!mnemonic) {
return 0;
}
@ -133,7 +127,8 @@ int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy)
return 0;
}
current_word[j] = mnemonic[i];
i++; j++;
i++;
j++;
}
current_word[j] = 0;
if (mnemonic[i] != 0) {
@ -163,8 +158,7 @@ int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy)
return n * 11;
}
int mnemonic_check(const char *mnemonic)
{
int mnemonic_check(const char *mnemonic) {
uint8_t bits[32 + 1];
int seed_len = mnemonic_to_entropy(mnemonic, bits);
if (seed_len != (12 * 11) && seed_len != (18 * 11) && seed_len != (24 * 11)) {
@ -185,8 +179,10 @@ int mnemonic_check(const char *mnemonic)
}
// passphrase must be at most 256 characters otherwise it would be truncated
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total))
{
void mnemonic_to_seed(const char *mnemonic, const char *passphrase,
uint8_t seed[512 / 8],
void (*progress_callback)(uint32_t current,
uint32_t total)) {
int mnemoniclen = strlen(mnemonic);
int passphraselen = strnlen(passphrase, 256);
#if USE_BIP39_CACHE
@ -206,14 +202,16 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed
memcpy(salt, "mnemonic", 8);
memcpy(salt + 8, passphrase, passphraselen);
static CONFIDENTIAL PBKDF2_HMAC_SHA512_CTX pctx;
pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, mnemoniclen, salt, passphraselen + 8, 1);
pbkdf2_hmac_sha512_Init(&pctx, (const uint8_t *)mnemonic, mnemoniclen, salt,
passphraselen + 8, 1);
if (progress_callback) {
progress_callback(0, BIP39_PBKDF2_ROUNDS);
}
for (int i = 0; i < 16; i++) {
pbkdf2_hmac_sha512_Update(&pctx, BIP39_PBKDF2_ROUNDS / 16);
if (progress_callback) {
progress_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 16, BIP39_PBKDF2_ROUNDS);
progress_callback((i + 1) * BIP39_PBKDF2_ROUNDS / 16,
BIP39_PBKDF2_ROUNDS);
}
}
pbkdf2_hmac_sha512_Final(&pctx, seed);
@ -230,7 +228,4 @@ void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed
#endif
}
const char * const *mnemonic_wordlist(void)
{
return wordlist;
}
const char *const *mnemonic_wordlist(void) { return wordlist; }

@ -37,8 +37,11 @@ int mnemonic_check(const char *mnemonic);
int mnemonic_to_entropy(const char *mnemonic, uint8_t *entropy);
// passphrase must be at most 256 characters otherwise it would be truncated
void mnemonic_to_seed(const char *mnemonic, const char *passphrase, uint8_t seed[512 / 8], void (*progress_callback)(uint32_t current, uint32_t total));
void mnemonic_to_seed(const char *mnemonic, const char *passphrase,
uint8_t seed[512 / 8],
void (*progress_callback)(uint32_t current,
uint32_t total));
const char * const *mnemonic_wordlist(void);
const char *const *mnemonic_wordlist(void);
#endif

File diff suppressed because it is too large Load Diff

@ -1,39 +1,25 @@
static inline uint32_t load32( const void *src )
{
static inline uint32_t load32(const void *src) {
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
}
static inline uint64_t load64( const void *src )
{
static inline uint64_t load64(const void *src) {
uint64_t w;
memcpy(&w, src, sizeof w);
return w;
}
static inline void store16( void *dst, uint16_t w )
{
memcpy(dst, &w, sizeof w);
}
static inline void store16(void *dst, uint16_t w) { memcpy(dst, &w, sizeof w); }
static inline void store32( void *dst, uint32_t w )
{
memcpy(dst, &w, sizeof w);
}
static inline void store32(void *dst, uint32_t w) { memcpy(dst, &w, sizeof w); }
static inline void store64( void *dst, uint64_t w )
{
memcpy(dst, &w, sizeof w);
}
static inline void store64(void *dst, uint64_t w) { memcpy(dst, &w, sizeof w); }
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
static inline uint32_t rotr32(const uint32_t w, const unsigned c) {
return (w >> c) | (w << (32 - c));
}
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 64 - c ) );
static inline uint64_t rotr64(const uint64_t w, const unsigned c) {
return (w >> c) | (w << (64 - c));
}

@ -19,8 +19,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "cash_addr.h"
@ -33,8 +33,7 @@
uint64_t cashaddr_polymod_step(uint64_t pre) {
uint8_t b = pre >> 35;
return ((pre & 0x7FFFFFFFFULL) << 5) ^
(-((b >> 0) & 1) & 0x98f2bc8e61ULL) ^
return ((pre & 0x7FFFFFFFFULL) << 5) ^ (-((b >> 0) & 1) & 0x98f2bc8e61ULL) ^
(-((b >> 1) & 1) & 0x79b76d99e2ULL) ^
(-((b >> 2) & 1) & 0xf33e5fb3c4ULL) ^
(-((b >> 3) & 1) & 0xae2eabe2a8ULL) ^
@ -44,17 +43,16 @@ uint64_t cashaddr_polymod_step(uint64_t pre) {
static const char* charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
static const int8_t charset_rev[128] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
};
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, -1, 10, 17, 21, 20, 26, 30, 7,
5, -1, -1, -1, -1, -1, -1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22,
31, 27, 19, -1, 1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1,
-1, -1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1, 1, 0,
3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1};
int cash_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) {
int cash_encode(char* output, const char* hrp, const uint8_t* data,
size_t data_len) {
uint64_t chk = 1;
size_t i = 0;
while (hrp[i] != 0) {
@ -87,7 +85,7 @@ int cash_encode(char *output, const char *hrp, const uint8_t *data, size_t data_
return 1;
}
int cash_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) {
int cash_decode(char* hrp, uint8_t* data, size_t* data_len, const char* input) {
uint64_t chk = 1;
size_t i;
size_t input_len = strlen(input);
@ -102,7 +100,8 @@ int cash_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) {
}
hrp_len = input_len - (1 + *data_len);
if (1 + *data_len >= input_len || hrp_len > MAX_HRP_SIZE ||
*data_len < CHECKSUM_SIZE || *data_len > CHECKSUM_SIZE + MAX_BASE32_SIZE) {
*data_len < CHECKSUM_SIZE ||
*data_len > CHECKSUM_SIZE + MAX_BASE32_SIZE) {
return 0;
}
// subtract checksum
@ -143,7 +142,8 @@ int cash_decode(char* hrp, uint8_t *data, size_t *data_len, const char *input) {
return chk == 1;
}
static int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t* in, size_t inlen, int inbits, int pad) {
static int convert_bits(uint8_t* out, size_t* outlen, int outbits,
const uint8_t* in, size_t inlen, int inbits, int pad) {
uint32_t val = 0;
int bits = 0;
uint32_t maxv = (((uint32_t)1) << outbits) - 1;
@ -165,7 +165,8 @@ static int convert_bits(uint8_t* out, size_t* outlen, int outbits, const uint8_t
return 1;
}
int cash_addr_encode(char *output, const char *hrp, const uint8_t *data, size_t data_len) {
int cash_addr_encode(char* output, const char* hrp, const uint8_t* data,
size_t data_len) {
uint8_t base32[MAX_BASE32_SIZE];
size_t base32len = 0;
if (data_len < 2 || data_len > MAX_DATA_SIZE) return 0;
@ -173,9 +174,10 @@ int cash_addr_encode(char *output, const char *hrp, const uint8_t *data, size_t
return cash_encode(output, hrp, base32, base32len);
}
int cash_addr_decode(uint8_t* witdata, size_t* witdata_len, const char* hrp, const char* addr) {
int cash_addr_decode(uint8_t* witdata, size_t* witdata_len, const char* hrp,
const char* addr) {
uint8_t data[MAX_BASE32_SIZE];
char hrp_actual[MAX_HRP_SIZE+1];
char hrp_actual[MAX_HRP_SIZE + 1];
size_t data_len;
if (!cash_decode(hrp_actual, data, &data_len, addr)) return 0;
if (data_len == 0 || data_len > MAX_BASE32_SIZE) return 0;

@ -34,30 +34,20 @@
* prog_len: Number of data bytes in prog.
* Returns 1 if successful.
*/
int cash_addr_encode(
char *output,
const char *hrp,
const uint8_t *prog,
size_t prog_len
);
int cash_addr_encode(char *output, const char *hrp, const uint8_t *prog,
size_t prog_len);
/** Decode a CashAddr address
*
* Out: prog: Pointer to a buffer of size 65 that will be updated to
* contain the witness program bytes.
* prog_len: Pointer to a size_t that will be updated to contain the length
* of bytes in prog.
* hrp: Pointer to the null-terminated human readable part that is
* expected (chain/network specific).
* addr: Pointer to the null-terminated address.
* Returns 1 if successful.
* prog_len: Pointer to a size_t that will be updated to contain the
* length of bytes in prog. hrp: Pointer to the null-terminated human
* readable part that is expected (chain/network specific). addr: Pointer to
* the null-terminated address. Returns 1 if successful.
*/
int cash_addr_decode(
uint8_t* prog,
size_t* prog_len,
const char* hrp,
const char* addr
);
int cash_addr_decode(uint8_t *prog, size_t *prog_len, const char *hrp,
const char *addr);
/** Encode a Cash string
*
@ -68,12 +58,8 @@ int cash_addr_decode(
* data_len: Length of the data array.
* Returns 1 if successful.
*/
int cash_encode(
char *output,
const char *hrp,
const uint8_t *data,
size_t data_len
);
int cash_encode(char *output, const char *hrp, const uint8_t *data,
size_t data_len);
/** Decode a Cash string
*
@ -86,11 +72,6 @@ int cash_encode(
* In: input: Pointer to a null-terminated Cash string.
* Returns 1 if succesful.
*/
int cash_decode(
char *hrp,
uint8_t *data,
size_t *data_len,
const char *input
);
int cash_decode(char *hrp, uint8_t *data, size_t *data_len, const char *input);
#endif

@ -22,30 +22,27 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "address.h"
#include "base58.h"
#include "bignum.h"
#include "rand.h"
#include "hmac.h"
#include "ecdsa.h"
#include "base58.h"
#include "secp256k1.h"
#include "rfc6979.h"
#include "hmac.h"
#include "memzero.h"
#include "rand.h"
#include "rfc6979.h"
#include "secp256k1.h"
// Set cp2 = cp1
void point_copy(const curve_point *cp1, curve_point *cp2)
{
*cp2 = *cp1;
}
void point_copy(const curve_point *cp1, curve_point *cp2) { *cp2 = *cp1; }
// cp2 = cp1 + cp2
void point_add(const ecdsa_curve *curve, const curve_point *cp1, curve_point *cp2)
{
void point_add(const ecdsa_curve *curve, const curve_point *cp1,
curve_point *cp2) {
bignum256 lambda, inv, xr, yr;
if (point_is_infinity(cp1)) {
@ -90,8 +87,7 @@ void point_add(const ecdsa_curve *curve, const curve_point *cp1, curve_point *cp
}
// cp = cp + cp
void point_double(const ecdsa_curve *curve, curve_point *cp)
{
void point_double(const ecdsa_curve *curve, curve_point *cp) {
bignum256 lambda, xr, yr;
if (point_is_infinity(cp)) {
@ -134,29 +130,25 @@ void point_double(const ecdsa_curve *curve, curve_point *cp)
}
// set point to internal representation of point at infinity
void point_set_infinity(curve_point *p)
{
void point_set_infinity(curve_point *p) {
bn_zero(&(p->x));
bn_zero(&(p->y));
}
// return true iff p represent point at infinity
// both coords are zero in internal representation
int point_is_infinity(const curve_point *p)
{
int point_is_infinity(const curve_point *p) {
return bn_is_zero(&(p->x)) && bn_is_zero(&(p->y));
}
// return true iff both points are equal
int point_is_equal(const curve_point *p, const curve_point *q)
{
int point_is_equal(const curve_point *p, const curve_point *q) {
return bn_is_equal(&(p->x), &(q->x)) && bn_is_equal(&(p->y), &(q->y));
}
// returns true iff p == -q
// expects p and q be valid points on curve other than point at infinity
int point_is_negative_of(const curve_point *p, const curve_point *q)
{
int point_is_negative_of(const curve_point *p, const curve_point *q) {
// if P == (x, y), then -P would be (x, -y) on this curve
if (!bn_is_equal(&(p->x), &(q->x))) {
return 0;
@ -172,17 +164,16 @@ int point_is_negative_of(const curve_point *p, const curve_point *q)
// Negate a (modulo prime) if cond is 0xffffffff, keep it if cond is 0.
// The timing of this function does not depend on cond.
void conditional_negate(uint32_t cond, bignum256 *a, const bignum256 *prime)
{
void conditional_negate(uint32_t cond, bignum256 *a, const bignum256 *prime) {
int j;
uint32_t tmp = 1;
assert(a->val[8] < 0x20000);
for (j = 0; j < 8; j++) {
tmp += 0x3fffffff + 2*prime->val[j] - a->val[j];
tmp += 0x3fffffff + 2 * prime->val[j] - a->val[j];
a->val[j] = ((tmp & 0x3fffffff) & cond) | (a->val[j] & ~cond);
tmp >>= 30;
}
tmp += 0x3fffffff + 2*prime->val[j] - a->val[j];
tmp += 0x3fffffff + 2 * prime->val[j] - a->val[j];
a->val[j] = ((tmp & 0x3fffffff) & cond) | (a->val[j] & ~cond);
assert(a->val[8] < 0x20000);
}
@ -203,7 +194,8 @@ static void generate_k_random(bignum256 *k, const bignum256 *prime) {
} while (bn_is_zero(k) || !bn_is_less(k, prime));
}
void curve_to_jacobian(const curve_point *p, jacobian_curve_point *jp, const bignum256 *prime) {
void curve_to_jacobian(const curve_point *p, jacobian_curve_point *jp,
const bignum256 *prime) {
// randomize z coordinate
generate_k_random(&jp->z, prime);
@ -218,7 +210,8 @@ void curve_to_jacobian(const curve_point *p, jacobian_curve_point *jp, const big
bn_multiply(&p->y, &jp->y, prime);
}
void jacobian_to_curve(const jacobian_curve_point *jp, curve_point *p, const bignum256 *prime) {
void jacobian_to_curve(const jacobian_curve_point *jp, curve_point *p,
const bignum256 *prime) {
p->y = jp->z;
bn_inverse(&p->y, prime);
// p->y = z^-1
@ -235,7 +228,8 @@ void jacobian_to_curve(const jacobian_curve_point *jp, curve_point *p, const big
bn_mod(&p->y, prime);
}
void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, const ecdsa_curve *curve) {
void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2,
const ecdsa_curve *curve) {
bignum256 r, h, r2;
bignum256 hcby, hsqx;
bignum256 xz, yz, az;
@ -243,7 +237,7 @@ void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, const e
const bignum256 *prime = &curve->prime;
int a = curve->a;
assert (-3 <= a && a <= 0);
assert(-3 <= a && a <= 0);
/* First we bring p1 to the same denominator:
* x1' := x1 * z2^2
@ -321,7 +315,6 @@ void point_jacobian_add(const curve_point *p1, jacobian_curve_point *p2, const e
bn_cmov(&r, is_doubling, &r2, &r);
bn_cmov(&h, is_doubling, &yz, &h);
// hsqx = h^2
hsqx = h;
bn_multiply(&hsqx, &hsqx, prime);
@ -358,7 +351,7 @@ void point_jacobian_double(jacobian_curve_point *p, const ecdsa_curve *curve) {
bignum256 az4, m, msq, ysq, xysq;
const bignum256 *prime = &curve->prime;
assert (-3 <= curve->a && curve->a <= 0);
assert(-3 <= curve->a && curve->a <= 0);
/* usual algorithm:
*
* lambda = (3((x/z^2)^2 + a) / 2y/z^3) = (3x^2 + az^4)/2yz
@ -423,13 +416,13 @@ void point_jacobian_double(jacobian_curve_point *p, const ecdsa_curve *curve) {
}
// res = k * p
void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_point *p, curve_point *res)
{
void point_multiply(const ecdsa_curve *curve, const bignum256 *k,
const curve_point *p, curve_point *res) {
// this algorithm is loosely based on
// Katsuyuki Okeya and Tsuyoshi Takagi, The Width-w NAF Method Provides
// Small Memory and Fast Elliptic Scalar Multiplications Secure against
// Side Channel Attacks.
assert (bn_is_less(k, &curve->order));
assert(bn_is_less(k, &curve->order));
int i, j;
static CONFIDENTIAL bignum256 a;
@ -485,7 +478,7 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_po
pmult[0] = *p;
for (i = 1; i < 8; i++) {
pmult[i] = pmult[7];
point_add(curve, &pmult[i-1], &pmult[i]);
point_add(curve, &pmult[i - 1], &pmult[i]);
}
// now compute res = sum_{i=0..63} a[i] * 16^i * p step by step,
@ -502,7 +495,7 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_po
sign = (bits >> 4) - 1;
bits ^= sign;
bits &= 15;
curve_to_jacobian(&pmult[bits>>1], &jres, prime);
curve_to_jacobian(&pmult[bits >> 1], &jres, prime);
for (i = 62; i >= 0; i--) {
// sign = sign(a[i+1]) (0xffffffff for negative, 0 for positive)
// invariant jres = (-1)^sign sum_{j=i+1..63} (a[j] * 16^{j-i-1} * p)
@ -548,9 +541,9 @@ void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_po
// res = k * G
// k must be a normalized number with 0 <= k < curve->order
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *res)
{
assert (bn_is_less(k, &curve->order));
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
curve_point *res) {
assert(bn_is_less(k, &curve->order));
int i, j;
static CONFIDENTIAL bignum256 a;
@ -605,7 +598,7 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *
lowbits ^= (lowbits >> 4) - 1;
lowbits &= 15;
curve_to_jacobian(&curve->cp[0][lowbits >> 1], &jres, prime);
for (i = 1; i < 64; i ++) {
for (i = 1; i < 64; i++) {
// invariant res = sign(a[i-1]) sum_{j=0..i-1} (a[j] * 16^j * G)
// shift a by 4 places.
@ -634,15 +627,15 @@ void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *
#else
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *res)
{
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
curve_point *res) {
point_multiply(curve, k, &curve->G, res);
}
#endif
int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *pub_key, uint8_t *session_key)
{
int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *pub_key, uint8_t *session_key) {
curve_point point;
if (!ecdsa_read_pubkey(curve, pub_key, &point)) {
return 1;
@ -661,12 +654,13 @@ int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8
return 0;
}
void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *state) {
uint8_t bx[2*32];
uint8_t buf[32 + 1 + 2*32];
void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash,
rfc6979_state *state) {
uint8_t bx[2 * 32];
uint8_t buf[32 + 1 + 2 * 32];
memcpy(bx, priv_key, 32);
memcpy(bx+32, hash, 32);
memcpy(bx + 32, hash, 32);
memset(state->v, 1, sizeof(state->v));
memset(state->k, 0, sizeof(state->k));
@ -688,8 +682,7 @@ void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *s
}
// generate next number from deterministic random number generator
void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state)
{
void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state) {
uint8_t buf[32 + 1];
hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v);
@ -703,8 +696,7 @@ void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state)
// generate K in a deterministic way, according to RFC6979
// http://tools.ietf.org/html/rfc6979
void generate_k_rfc6979(bignum256 *k, rfc6979_state *state)
{
void generate_k_rfc6979(bignum256 *k, rfc6979_state *state) {
uint8_t buf[32];
generate_rfc6979(buf, state);
bn_read_be(buf, k);
@ -713,14 +705,15 @@ void generate_k_rfc6979(bignum256 *k, rfc6979_state *state)
// msg is a data to be signed
// msg_len is the message length
int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]))
{
int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
uint8_t hash[32];
hasher_Raw(hasher_sign, msg, msg_len, hash);
int res = ecdsa_sign_digest(curve, priv_key, hash, sig, pby, is_canonical);
memzero(hash, sizeof(hash));
return res;
}
// uses secp256k1 curve
@ -729,8 +722,9 @@ int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, const uint8_t *
// digest is 32 bytes of digest
// is_canonical is an optional function that checks if the signature
// conforms to additional coin-specific rules.
int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]))
{
int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *digest, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64])) {
int i;
curve_point R;
bignum256 k, z, randk;
@ -745,7 +739,6 @@ int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const u
bn_read_be(digest, &z);
for (i = 0; i < 10000; i++) {
#if USE_RFC6979
// generate K deterministically
generate_k_rfc6979(&k, &rng);
@ -822,8 +815,8 @@ int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const u
return -1;
}
void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key)
{
void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key) {
curve_point R;
bignum256 k;
@ -836,8 +829,8 @@ void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, u
memzero(&k, sizeof(k));
}
void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key)
{
void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key) {
curve_point R;
bignum256 k;
@ -851,8 +844,8 @@ void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, u
memzero(&k, sizeof(k));
}
int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, uint8_t *uncompressed)
{
int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key,
uint8_t *uncompressed) {
curve_point pub;
if (!ecdsa_read_pubkey(curve, pub_key, &pub)) {
@ -866,8 +859,8 @@ int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, ui
return 1;
}
void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, uint8_t *pubkeyhash)
{
void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey,
uint8_t *pubkeyhash) {
uint8_t h[HASHER_DIGEST_LENGTH];
if (pub_key[0] == 0x04) { // uncompressed format
hasher_Raw(hasher_pubkey, pub_key, 65, h);
@ -880,15 +873,16 @@ void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, uint
memzero(h, sizeof(h));
}
void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, uint8_t *addr_raw)
{
void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey, uint8_t *addr_raw) {
size_t prefix_len = address_prefix_bytes_len(version);
address_write_prefix_bytes(version, addr_raw);
ecdsa_get_pubkeyhash(pub_key, hasher_pubkey, addr_raw + prefix_len);
}
void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize)
{
void ecdsa_get_address(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey, HasherType hasher_base58,
char *addr, int addrsize) {
uint8_t raw[MAX_ADDR_RAW_SIZE];
size_t prefix_len = address_prefix_bytes_len(version);
ecdsa_get_address_raw(pub_key, version, hasher_pubkey, raw);
@ -897,8 +891,9 @@ void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, HasherType hash
memzero(raw, sizeof(raw));
}
void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, uint8_t *addr_raw)
{
void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey,
uint8_t *addr_raw) {
uint8_t buf[32 + 2];
buf[0] = 0; // version byte
buf[1] = 20; // push 20 bytes
@ -908,8 +903,10 @@ void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version,
hasher_Raw(hasher_pubkey, buf, 22, addr_raw + prefix_len);
}
void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize)
{
void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey,
HasherType hasher_base58, char *addr,
int addrsize) {
uint8_t raw[MAX_ADDR_RAW_SIZE];
size_t prefix_len = address_prefix_bytes_len(version);
ecdsa_get_address_segwit_p2sh_raw(pub_key, version, hasher_pubkey, raw);
@ -917,28 +914,30 @@ void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, Has
memzero(raw, sizeof(raw));
}
void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, HasherType hasher_base58, char *wif, int wifsize)
{
void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version,
HasherType hasher_base58, char *wif, int wifsize) {
uint8_t wif_raw[MAX_WIF_RAW_SIZE];
size_t prefix_len = address_prefix_bytes_len(version);
address_write_prefix_bytes(version, wif_raw);
memcpy(wif_raw + prefix_len, priv_key, 32);
wif_raw[prefix_len + 32] = 0x01;
base58_encode_check(wif_raw, prefix_len + 32 + 1, hasher_base58, wif, wifsize);
base58_encode_check(wif_raw, prefix_len + 32 + 1, hasher_base58, wif,
wifsize);
// private keys running around our stack can cause trouble
memzero(wif_raw, sizeof(wif_raw));
}
int ecdsa_address_decode(const char *addr, uint32_t version, HasherType hasher_base58, uint8_t *out)
{
int ecdsa_address_decode(const char *addr, uint32_t version,
HasherType hasher_base58, uint8_t *out) {
if (!addr) return 0;
int prefix_len = address_prefix_bytes_len(version);
return base58_decode_check(addr, hasher_base58, out, 20 + prefix_len) == 20 + prefix_len
&& address_check_prefix(out, version);
return base58_decode_check(addr, hasher_base58, out, 20 + prefix_len) ==
20 + prefix_len &&
address_check_prefix(out, version);
}
void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x, bignum256 *y)
{
void uncompress_coords(const ecdsa_curve *curve, uint8_t odd,
const bignum256 *x, bignum256 *y) {
// y^2 = x^3 + a*x + b
memcpy(y, x, sizeof(bignum256)); // y is x
bn_multiply(x, y, &curve->prime); // y is x^2
@ -951,8 +950,8 @@ void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x
}
}
int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub)
{
int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key,
curve_point *pub) {
if (!curve) {
curve = &secp256k1;
}
@ -975,15 +974,15 @@ int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_po
// - pub->x and pub->y are in range [0,p-1].
// - pub is on the curve.
int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub)
{
int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub) {
bignum256 y_2, x3_ax_b;
if (point_is_infinity(pub)) {
return 0;
}
if (!bn_is_less(&(pub->x), &curve->prime) || !bn_is_less(&(pub->y), &curve->prime)) {
if (!bn_is_less(&(pub->x), &curve->prime) ||
!bn_is_less(&(pub->y), &curve->prime)) {
return 0;
}
@ -1014,8 +1013,9 @@ int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub)
// msg is a data that was signed
// msg_len is the message length
int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len)
{
int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg,
uint32_t msg_len) {
uint8_t hash[32];
hasher_Raw(hasher_sign, msg, msg_len, hash);
int res = ecdsa_verify_digest(curve, pub_key, sig, hash);
@ -1025,8 +1025,9 @@ int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, const uint8_t
// Compute public key from signature and recovery id.
// returns 0 if the key is successfully recovered
int ecdsa_recover_pub_from_sig (const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest, int recid)
{
int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key,
const uint8_t *sig, const uint8_t *digest,
int recid) {
bignum256 r, s, e;
curve_point cp, cp2;
@ -1074,8 +1075,8 @@ int ecdsa_recover_pub_from_sig (const ecdsa_curve *curve, uint8_t *pub_key, cons
}
// returns 0 if verification succeeded
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest)
{
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key,
const uint8_t *sig, const uint8_t *digest) {
curve_point pub, res;
bignum256 r, s, z;
@ -1088,9 +1089,9 @@ int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const
bn_read_be(digest, &z);
if (bn_is_zero(&r) || bn_is_zero(&s) ||
(!bn_is_less(&r, &curve->order)) ||
(!bn_is_less(&s, &curve->order))) return 2;
if (bn_is_zero(&r) || bn_is_zero(&s) || (!bn_is_less(&r, &curve->order)) ||
(!bn_is_less(&s, &curve->order)))
return 2;
bn_inverse(&s, &curve->order); // s^-1
bn_multiply(&s, &z, &curve->order); // z*s^-1
@ -1108,7 +1109,8 @@ int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const
}
if (result == 0) {
// both pub and res can be infinity, can have y = 0 OR can be equal -> false negative
// both pub and res can be infinity, can have y = 0 OR can be equal -> false
// negative
point_multiply(curve, &s, &pub, &pub);
point_add(curve, &pub, &res);
bn_mod(&(res.x), &curve->order);
@ -1128,37 +1130,59 @@ int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const
return result;
}
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der)
{
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der) {
int i;
uint8_t *p = der, *len, *len1, *len2;
*p = 0x30; p++; // sequence
*p = 0x00; len = p; p++; // len(sequence)
*p = 0x02; p++; // integer
*p = 0x00; len1 = p; p++; // len(integer)
*p = 0x30;
p++; // sequence
*p = 0x00;
len = p;
p++; // len(sequence)
*p = 0x02;
p++; // integer
*p = 0x00;
len1 = p;
p++; // len(integer)
// process R
i = 0;
while (sig[i] == 0 && i < 32) { i++; } // skip leading zeroes
while (sig[i] == 0 && i < 32) {
i++;
} // skip leading zeroes
if (sig[i] >= 0x80) { // put zero in output if MSB set
*p = 0x00; p++; *len1 = *len1 + 1;
*p = 0x00;
p++;
*len1 = *len1 + 1;
}
while (i < 32) { // copy bytes to output
*p = sig[i]; p++; *len1 = *len1 + 1; i++;
*p = sig[i];
p++;
*len1 = *len1 + 1;
i++;
}
*p = 0x02; p++; // integer
*p = 0x00; len2 = p; p++; // len(integer)
*p = 0x02;
p++; // integer
*p = 0x00;
len2 = p;
p++; // len(integer)
// process S
i = 32;
while (sig[i] == 0 && i < 64) { i++; } // skip leading zeroes
while (sig[i] == 0 && i < 64) {
i++;
} // skip leading zeroes
if (sig[i] >= 0x80) { // put zero in output if MSB set
*p = 0x00; p++; *len2 = *len2 + 1;
*p = 0x00;
p++;
*len2 = *len2 + 1;
}
while (i < 64) { // copy bytes to output
*p = sig[i]; p++; *len2 = *len2 + 1; i++;
*p = sig[i];
p++;
*len2 = *len2 + 1;
i++;
}
*len = *len1 + *len2 + 4;

@ -25,9 +25,9 @@
#define __ECDSA_H__
#include <stdint.h>
#include "options.h"
#include "bignum.h"
#include "hasher.h"
#include "options.h"
// curve point x and y
typedef struct {
@ -35,7 +35,6 @@ typedef struct {
} curve_point;
typedef struct {
bignum256 prime; // prime order of the finite field
curve_point G; // initial curve point
bignum256 order; // order of G
@ -63,35 +62,65 @@ typedef struct {
#define MAX_WIF_SIZE (57)
void point_copy(const curve_point *cp1, curve_point *cp2);
void point_add(const ecdsa_curve *curve, const curve_point *cp1, curve_point *cp2);
void point_add(const ecdsa_curve *curve, const curve_point *cp1,
curve_point *cp2);
void point_double(const ecdsa_curve *curve, curve_point *cp);
void point_multiply(const ecdsa_curve *curve, const bignum256 *k, const curve_point *p, curve_point *res);
void point_multiply(const ecdsa_curve *curve, const bignum256 *k,
const curve_point *p, curve_point *res);
void point_set_infinity(curve_point *p);
int point_is_infinity(const curve_point *p);
int point_is_equal(const curve_point *p, const curve_point *q);
int point_is_negative_of(const curve_point *p, const curve_point *q);
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k, curve_point *res);
int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *pub_key, uint8_t *session_key);
void uncompress_coords(const ecdsa_curve *curve, uint8_t odd, const bignum256 *x, bignum256 *y);
int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, uint8_t *uncompressed);
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
curve_point *res);
int ecdh_multiply(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *pub_key, uint8_t *session_key);
void uncompress_coords(const ecdsa_curve *curve, uint8_t odd,
const bignum256 *x, bignum256 *y);
int ecdsa_uncompress_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key,
uint8_t *uncompressed);
int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign, const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key, const uint8_t *digest, uint8_t *sig, uint8_t *pby, int (*is_canonical)(uint8_t by, uint8_t sig[64]));
void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key);
void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key, uint8_t *pub_key);
void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey, uint8_t *pubkeyhash);
void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, uint8_t *addr_raw);
void ecdsa_get_address(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize);
void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, uint8_t *addr_raw);
void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version, HasherType hasher_pubkey, HasherType hasher_base58, char *addr, int addrsize);
void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version, HasherType hasher_base58, char *wif, int wifsize);
int ecdsa_sign(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *priv_key, const uint8_t *msg, uint32_t msg_len,
uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
int ecdsa_sign_digest(const ecdsa_curve *curve, const uint8_t *priv_key,
const uint8_t *digest, uint8_t *sig, uint8_t *pby,
int (*is_canonical)(uint8_t by, uint8_t sig[64]));
void ecdsa_get_public_key33(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key);
void ecdsa_get_public_key65(const ecdsa_curve *curve, const uint8_t *priv_key,
uint8_t *pub_key);
void ecdsa_get_pubkeyhash(const uint8_t *pub_key, HasherType hasher_pubkey,
uint8_t *pubkeyhash);
void ecdsa_get_address_raw(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey, uint8_t *addr_raw);
void ecdsa_get_address(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey, HasherType hasher_base58,
char *addr, int addrsize);
void ecdsa_get_address_segwit_p2sh_raw(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey,
uint8_t *addr_raw);
void ecdsa_get_address_segwit_p2sh(const uint8_t *pub_key, uint32_t version,
HasherType hasher_pubkey,
HasherType hasher_base58, char *addr,
int addrsize);
void ecdsa_get_wif(const uint8_t *priv_key, uint32_t version,
HasherType hasher_base58, char *wif, int wifsize);
int ecdsa_address_decode(const char *addr, uint32_t version, HasherType hasher_base58, uint8_t *out);
int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key, curve_point *pub);
int ecdsa_address_decode(const char *addr, uint32_t version,
HasherType hasher_base58, uint8_t *out);
int ecdsa_read_pubkey(const ecdsa_curve *curve, const uint8_t *pub_key,
curve_point *pub);
int ecdsa_validate_pubkey(const ecdsa_curve *curve, const curve_point *pub);
int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg, uint32_t msg_len);
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest);
int ecdsa_recover_pub_from_sig (const ecdsa_curve *curve, uint8_t *pub_key, const uint8_t *sig, const uint8_t *digest, int recid);
int ecdsa_verify(const ecdsa_curve *curve, HasherType hasher_sign,
const uint8_t *pub_key, const uint8_t *sig, const uint8_t *msg,
uint32_t msg_len);
int ecdsa_verify_digest(const ecdsa_curve *curve, const uint8_t *pub_key,
const uint8_t *sig, const uint8_t *digest);
int ecdsa_recover_pub_from_sig(const ecdsa_curve *curve, uint8_t *pub_key,
const uint8_t *sig, const uint8_t *digest,
int recid);
int ecdsa_sig_to_der(const uint8_t *sig, uint8_t *der);
#endif

@ -23,7 +23,8 @@
#include "hasher.h"
#include "ripemd160.h"
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param, uint32_t param_size) {
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param,
uint32_t param_size) {
hasher->type = type;
hasher->param = param;
hasher->param_size = param_size;
@ -52,7 +53,8 @@ void hasher_InitParam(Hasher *hasher, HasherType type, const void *param, uint32
blake2b_Init(&hasher->ctx.blake2b, 32);
break;
case HASHER_BLAKE2B_PERSONAL:
blake2b_InitPersonal(&hasher->ctx.blake2b, 32, hasher->param, hasher->param_size);
blake2b_InitPersonal(&hasher->ctx.blake2b, 32, hasher->param,
hasher->param_size);
break;
}
}
@ -135,7 +137,8 @@ void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]) {
}
}
void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]) {
void hasher_Raw(HasherType type, const uint8_t *data, size_t length,
uint8_t hash[HASHER_DIGEST_LENGTH]) {
Hasher hasher;
hasher_Init(&hasher, type);

@ -26,11 +26,11 @@
#include <stddef.h>
#include <stdint.h>
#include "sha2.h"
#include "sha3.h"
#include "blake256.h"
#include "groestl.h"
#include "blake2b.h"
#include "groestl.h"
#include "sha2.h"
#include "sha3.h"
#define HASHER_DIGEST_LENGTH 32
@ -69,12 +69,14 @@ typedef struct {
uint32_t param_size;
} Hasher;
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param, uint32_t param_size);
void hasher_InitParam(Hasher *hasher, HasherType type, const void *param,
uint32_t param_size);
void hasher_Init(Hasher *hasher, HasherType type);
void hasher_Reset(Hasher *hasher);
void hasher_Update(Hasher *hasher, const uint8_t *data, size_t length);
void hasher_Final(Hasher *hasher, uint8_t hash[HASHER_DIGEST_LENGTH]);
void hasher_Raw(HasherType type, const uint8_t *data, size_t length, uint8_t hash[HASHER_DIGEST_LENGTH]);
void hasher_Raw(HasherType type, const uint8_t *data, size_t length,
uint8_t hash[HASHER_DIGEST_LENGTH]);
#endif

@ -24,11 +24,11 @@
#include <string.h>
#include "hmac.h"
#include "options.h"
#include "memzero.h"
#include "options.h"
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen)
{
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key,
const uint32_t keylen) {
static CONFIDENTIAL uint8_t i_key_pad[SHA256_BLOCK_LENGTH];
memzero(i_key_pad, SHA256_BLOCK_LENGTH);
if (keylen > SHA256_BLOCK_LENGTH) {
@ -45,13 +45,12 @@ void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t
memzero(i_key_pad, sizeof(i_key_pad));
}
void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_t msglen)
{
void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg,
const uint32_t msglen) {
sha256_Update(&(hctx->ctx), msg, msglen);
}
void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac)
{
void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac) {
sha256_Final(&(hctx->ctx), hmac);
sha256_Init(&(hctx->ctx));
sha256_Update(&(hctx->ctx), hctx->o_key_pad, SHA256_BLOCK_LENGTH);
@ -60,30 +59,30 @@ void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac)
memzero(hctx, sizeof(HMAC_SHA256_CTX));
}
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
{
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
const uint32_t msglen, uint8_t *hmac) {
static CONFIDENTIAL HMAC_SHA256_CTX hctx;
hmac_sha256_Init(&hctx, key, keylen);
hmac_sha256_Update(&hctx, msg, msglen);
hmac_sha256_Final(&hctx, hmac);
}
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest)
{
static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH/sizeof(uint32_t)];
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen,
uint32_t *opad_digest, uint32_t *ipad_digest) {
static CONFIDENTIAL uint32_t key_pad[SHA256_BLOCK_LENGTH / sizeof(uint32_t)];
memzero(key_pad, sizeof(key_pad));
if (keylen > SHA256_BLOCK_LENGTH) {
static CONFIDENTIAL SHA256_CTX context;
sha256_Init(&context);
sha256_Update(&context, key, keylen);
sha256_Final(&context, (uint8_t*)key_pad);
sha256_Final(&context, (uint8_t *)key_pad);
} else {
memcpy(key_pad, key, keylen);
}
/* compute o_key_pad and its digest */
for (int i = 0; i < SHA256_BLOCK_LENGTH/(int)sizeof(uint32_t); i++) {
for (int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) {
uint32_t data;
#if BYTE_ORDER == LITTLE_ENDIAN
REVERSE32(key_pad[i], data);
@ -95,15 +94,15 @@ void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *op
sha256_Transform(sha256_initial_hash_value, key_pad, opad_digest);
/* convert o_key_pad to i_key_pad and compute its digest */
for (int i = 0; i < SHA256_BLOCK_LENGTH/(int)sizeof(uint32_t); i++) {
for (int i = 0; i < SHA256_BLOCK_LENGTH / (int)sizeof(uint32_t); i++) {
key_pad[i] = key_pad[i] ^ 0x5c5c5c5c ^ 0x36363636;
}
sha256_Transform(sha256_initial_hash_value, key_pad, ipad_digest);
memzero(key_pad, sizeof(key_pad));
}
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen)
{
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key,
const uint32_t keylen) {
static CONFIDENTIAL uint8_t i_key_pad[SHA512_BLOCK_LENGTH];
memzero(i_key_pad, SHA512_BLOCK_LENGTH);
if (keylen > SHA512_BLOCK_LENGTH) {
@ -120,13 +119,12 @@ void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t
memzero(i_key_pad, sizeof(i_key_pad));
}
void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_t msglen)
{
void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg,
const uint32_t msglen) {
sha512_Update(&(hctx->ctx), msg, msglen);
}
void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac)
{
void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac) {
sha512_Final(&(hctx->ctx), hmac);
sha512_Init(&(hctx->ctx));
sha512_Update(&(hctx->ctx), hctx->o_key_pad, SHA512_BLOCK_LENGTH);
@ -135,30 +133,30 @@ void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac)
memzero(hctx, sizeof(HMAC_SHA512_CTX));
}
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac)
{
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
const uint32_t msglen, uint8_t *hmac) {
HMAC_SHA512_CTX hctx;
hmac_sha512_Init(&hctx, key, keylen);
hmac_sha512_Update(&hctx, msg, msglen);
hmac_sha512_Final(&hctx, hmac);
}
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest)
{
static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH/sizeof(uint64_t)];
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen,
uint64_t *opad_digest, uint64_t *ipad_digest) {
static CONFIDENTIAL uint64_t key_pad[SHA512_BLOCK_LENGTH / sizeof(uint64_t)];
memzero(key_pad, sizeof(key_pad));
if (keylen > SHA512_BLOCK_LENGTH) {
static CONFIDENTIAL SHA512_CTX context;
sha512_Init(&context);
sha512_Update(&context, key, keylen);
sha512_Final(&context, (uint8_t*)key_pad);
sha512_Final(&context, (uint8_t *)key_pad);
} else {
memcpy(key_pad, key, keylen);
}
/* compute o_key_pad and its digest */
for (int i = 0; i < SHA512_BLOCK_LENGTH/(int)sizeof(uint64_t); i++) {
for (int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) {
uint64_t data;
#if BYTE_ORDER == LITTLE_ENDIAN
REVERSE64(key_pad[i], data);
@ -170,7 +168,7 @@ void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *op
sha512_Transform(sha512_initial_hash_value, key_pad, opad_digest);
/* convert o_key_pad to i_key_pad and compute its digest */
for (int i = 0; i < SHA512_BLOCK_LENGTH/(int)sizeof(uint64_t); i++) {
for (int i = 0; i < SHA512_BLOCK_LENGTH / (int)sizeof(uint64_t); i++) {
key_pad[i] = key_pad[i] ^ 0x5c5c5c5c5c5c5c5c ^ 0x3636363636363636;
}
sha512_Transform(sha512_initial_hash_value, key_pad, ipad_digest);

@ -37,16 +37,24 @@ typedef struct _HMAC_SHA512_CTX {
SHA512_CTX ctx;
} HMAC_SHA512_CTX;
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key, const uint32_t keylen);
void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg, const uint32_t msglen);
void hmac_sha256_Init(HMAC_SHA256_CTX *hctx, const uint8_t *key,
const uint32_t keylen);
void hmac_sha256_Update(HMAC_SHA256_CTX *hctx, const uint8_t *msg,
const uint32_t msglen);
void hmac_sha256_Final(HMAC_SHA256_CTX *hctx, uint8_t *hmac);
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac);
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *opad_digest, uint32_t *ipad_digest);
void hmac_sha256(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
const uint32_t msglen, uint8_t *hmac);
void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen,
uint32_t *opad_digest, uint32_t *ipad_digest);
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key, const uint32_t keylen);
void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg, const uint32_t msglen);
void hmac_sha512_Init(HMAC_SHA512_CTX *hctx, const uint8_t *key,
const uint32_t keylen);
void hmac_sha512_Update(HMAC_SHA512_CTX *hctx, const uint8_t *msg,
const uint32_t msglen);
void hmac_sha512_Final(HMAC_SHA512_CTX *hctx, uint8_t *hmac);
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t *hmac);
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen, uint64_t *opad_digest, uint64_t *ipad_digest);
void hmac_sha512(const uint8_t *key, const uint32_t keylen, const uint8_t *msg,
const uint32_t msglen, uint8_t *hmac);
void hmac_sha512_prepare(const uint8_t *key, const uint32_t keylen,
uint64_t *opad_digest, uint64_t *ipad_digest);
#endif

@ -18,12 +18,13 @@
#endif
// GNU C Library version 2.25 or later.
#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
#if defined(__GLIBC__) && \
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
#define HAVE_EXPLICIT_BZERO 1
#endif
// Newlib
#if defined( __NEWLIB__)
#if defined(__NEWLIB__)
#define HAVE_EXPLICIT_BZERO 1
#endif
@ -42,22 +43,21 @@
#define HAVE_EXPLICIT_MEMSET 1
#endif
// Adapted from https://github.com/jedisct1/libsodium/blob/1647f0d53ae0e370378a9195477e3df0a792408f/src/libsodium/sodium/utils.c#L102-L130
// Adapted from
// https://github.com/jedisct1/libsodium/blob/1647f0d53ae0e370378a9195477e3df0a792408f/src/libsodium/sodium/utils.c#L102-L130
void memzero(void *const pnt, const size_t len)
{
void memzero(void *const pnt, const size_t len) {
#ifdef _WIN32
SecureZeroMemory(pnt, len);
#elif defined(HAVE_MEMSET_S)
memset_s(pnt, (rsize_t) len, 0, (rsize_t) len);
memset_s(pnt, (rsize_t)len, 0, (rsize_t)len);
#elif defined(HAVE_EXPLICIT_BZERO)
explicit_bzero(pnt, len);
#elif defined(HAVE_EXPLICIT_MEMSET)
explicit_memset(pnt, 0, len);
#else
volatile unsigned char *volatile pnt_ =
(volatile unsigned char *volatile) pnt;
size_t i = (size_t) 0U;
volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile)pnt;
size_t i = (size_t)0U;
while (i < len) {
pnt_[i++] = 0U;

@ -3,6 +3,6 @@
#include <stddef.h>
void memzero(void * const pnt, const size_t len);
void memzero(void* const pnt, const size_t len);
#endif

@ -14,8 +14,8 @@
#endif
#include "base58.h"
#include "range_proof.h"
#include "serialize.h"
#include "xmr.h"
#include "range_proof.h"
#endif //TREZOR_CRYPTO_MONERO_H
#endif // TREZOR_CRYPTO_MONERO_H

@ -4,27 +4,27 @@
#include "range_proof.h"
static void xmr_hash_ge25519_to_scalar(bignum256modm r, const ge25519 *p){
static void xmr_hash_ge25519_to_scalar(bignum256modm r, const ge25519 *p) {
unsigned char buff[32];
ge25519_pack(buff, p);
xmr_hash_to_scalar(r, buff, sizeof(buff));
}
void xmr_gen_range_sig(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask, xmr_amount amount, bignum256modm * last_mask){
void xmr_gen_range_sig(xmr_range_sig_t *sig, ge25519 *C, bignum256modm mask,
xmr_amount amount, bignum256modm *last_mask) {
bignum256modm ai[64];
bignum256modm alpha[64];
xmr_gen_range_sig_ex(sig, C, mask, amount, last_mask, ai, alpha);
}
void xmr_gen_range_sig_ex(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask, xmr_amount amount, bignum256modm * last_mask,
bignum256modm ai[64], bignum256modm alpha[64])
{
void xmr_gen_range_sig_ex(xmr_range_sig_t *sig, ge25519 *C, bignum256modm mask,
xmr_amount amount, bignum256modm *last_mask,
bignum256modm ai[64], bignum256modm alpha[64]) {
const unsigned n = XMR_ATOMS;
bignum256modm a={0};
bignum256modm si={0};
bignum256modm c={0};
bignum256modm ee={0};
bignum256modm a = {0};
bignum256modm si = {0};
bignum256modm c = {0};
bignum256modm ee = {0};
unsigned char buff[32];
Hasher kck;
@ -41,16 +41,17 @@ void xmr_gen_range_sig_ex(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask
ge25519_set_xmr_h(&C_h);
set256_modm(a, 0);
#define BB(i) ((amount>>(i)) & 1)
#define BB(i) ((amount >> (i)) & 1)
// First pass, generates: ai, alpha, Ci, ee, s1
for(unsigned ii=0; ii<n; ++ii){
for (unsigned ii = 0; ii < n; ++ii) {
xmr_random_scalar(ai[ii]);
if (last_mask != NULL && ii == n - 1){
if (last_mask != NULL && ii == n - 1) {
sub256_modm(ai[ii], *last_mask, a);
}
add256_modm(a, a, ai[ii]); // creating the total mask since you have to pass this to receiver...
add256_modm(a, a, ai[ii]); // creating the total mask since you have to
// pass this to receiver...
xmr_random_scalar(alpha[ii]);
ge25519_scalarmult_base_niels(&L, ge25519_niels_base_multiples, alpha[ii]);
@ -87,8 +88,8 @@ void xmr_gen_range_sig_ex(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask
ge25519_set_xmr_h(&C_h);
// Second pass, s0, s1
for(unsigned ii=0; ii<n; ++ii){
if (BB(ii) == 0){
for (unsigned ii = 0; ii < n; ++ii) {
if (BB(ii) == 0) {
mulsub256_modm(si, ai[ii], ee, alpha[ii]);
contract256_modm(sig->asig.s0[ii], si);
@ -112,4 +113,3 @@ void xmr_gen_range_sig_ex(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask
contract256_modm(sig->asig.ee, ee);
#undef BB
}

@ -22,9 +22,10 @@ typedef struct range_sig {
xmr_key64_t Ci;
} xmr_range_sig_t;
void xmr_gen_range_sig(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask, xmr_amount amount, bignum256modm * last_mask);
void xmr_gen_range_sig_ex(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask, xmr_amount amount, bignum256modm * last_mask,
void xmr_gen_range_sig(xmr_range_sig_t* sig, ge25519* C, bignum256modm mask,
xmr_amount amount, bignum256modm* last_mask);
void xmr_gen_range_sig_ex(xmr_range_sig_t* sig, ge25519* C, bignum256modm mask,
xmr_amount amount, bignum256modm* last_mask,
bignum256modm ai[64], bignum256modm alpha[64]);
#endif //TREZOR_CRYPTO_RANGE_PROOF_H
#endif // TREZOR_CRYPTO_RANGE_PROOF_H

@ -4,7 +4,7 @@
#include "serialize.h"
int xmr_size_varint(uint64_t num){
int xmr_size_varint(uint64_t num) {
int ctr = 1;
while (num >= 0x80) {
++ctr;
@ -13,10 +13,10 @@ int xmr_size_varint(uint64_t num){
return ctr;
}
int xmr_write_varint(uint8_t * buff, size_t buff_size, uint64_t num){
int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num) {
unsigned ctr = 0;
while (num >= 0x80 && ctr < buff_size) {
*buff = (uint8_t) (((num) & 0x7f) | 0x80);
*buff = (uint8_t)(((num)&0x7f) | 0x80);
++buff;
++ctr;
num >>= 7;
@ -24,13 +24,13 @@ int xmr_write_varint(uint8_t * buff, size_t buff_size, uint64_t num){
/* writes the last one to dest */
if (ctr < buff_size) {
*buff = (uint8_t) num;
*buff = (uint8_t)num;
++ctr;
}
return ctr <= buff_size ? (int)ctr : -1;
}
int xmr_read_varint(uint8_t * buff, size_t buff_size, uint64_t *val) {
int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val) {
unsigned read = 0;
int finished_ok = 0;
*val = 0;
@ -51,4 +51,3 @@ int xmr_read_varint(uint8_t * buff, size_t buff_size, uint64_t *val) {
}
return finished_ok ? (int)read + 1 : -2;
}

@ -9,7 +9,7 @@
#include <stdint.h>
int xmr_size_varint(uint64_t num);
int xmr_write_varint(uint8_t * buff, size_t buff_size, uint64_t num);
int xmr_read_varint(uint8_t * buff, size_t buff_size, uint64_t *val);
int xmr_write_varint(uint8_t *buff, size_t buff_size, uint64_t num);
int xmr_read_varint(uint8_t *buff, size_t buff_size, uint64_t *val);
#endif //TREZOR_XMR_SERIALIZE_H
#endif // TREZOR_XMR_SERIALIZE_H

@ -4,55 +4,52 @@
#include "xmr.h"
#include "int-util.h"
#include "serialize.h"
#include "rand.h"
#include "serialize.h"
const ge25519 ALIGN(16) xmr_h = {
{0x1861ec7, 0x1ceac77, 0x2f11626, 0x1f261d3, 0x346107c, 0x06d8c4a, 0x254201d, 0x1675c09, 0x1301c3f, 0x0211d73},
{0x326feb4, 0x12e30cc, 0x0cf54b4, 0x1117305, 0x318f5d5, 0x06cf754, 0x2e578a1, 0x1daf058, 0x34430a1, 0x04410e9},
{0x0fde4d2, 0x0774049, 0x22ca951, 0x05aec2b, 0x07a36a5, 0x1394f13, 0x3c5385c, 0x1adb924, 0x2b6c581, 0x0a55fa4},
{0x24517f7, 0x05ee936, 0x3acf5d9, 0x14b08aa, 0x3363738, 0x1051745, 0x360601e, 0x0f3f2c9, 0x1ead2cd, 0x1d3e3df}
};
void ge25519_set_xmr_h(ge25519 *r){
ge25519_copy(r, &xmr_h);
}
void xmr_random_scalar(bignum256modm m){
unsigned char buff[32]={0};
{0x1861ec7, 0x1ceac77, 0x2f11626, 0x1f261d3, 0x346107c, 0x06d8c4a,
0x254201d, 0x1675c09, 0x1301c3f, 0x0211d73},
{0x326feb4, 0x12e30cc, 0x0cf54b4, 0x1117305, 0x318f5d5, 0x06cf754,
0x2e578a1, 0x1daf058, 0x34430a1, 0x04410e9},
{0x0fde4d2, 0x0774049, 0x22ca951, 0x05aec2b, 0x07a36a5, 0x1394f13,
0x3c5385c, 0x1adb924, 0x2b6c581, 0x0a55fa4},
{0x24517f7, 0x05ee936, 0x3acf5d9, 0x14b08aa, 0x3363738, 0x1051745,
0x360601e, 0x0f3f2c9, 0x1ead2cd, 0x1d3e3df}};
void ge25519_set_xmr_h(ge25519 *r) { ge25519_copy(r, &xmr_h); }
void xmr_random_scalar(bignum256modm m) {
unsigned char buff[32] = {0};
random_buffer(buff, sizeof(buff));
expand256_modm(m, buff, sizeof(buff));
}
void xmr_fast_hash(uint8_t * hash, const void *data, size_t length){
void xmr_fast_hash(uint8_t *hash, const void *data, size_t length) {
hasher_Raw(HASHER_SHA3K, data, length, hash);
}
void xmr_hasher_init(Hasher * hasher){
hasher_Init(hasher, HASHER_SHA3K);
}
void xmr_hasher_init(Hasher *hasher) { hasher_Init(hasher, HASHER_SHA3K); }
void xmr_hasher_update(Hasher * hasher, const void *data, size_t length){
void xmr_hasher_update(Hasher *hasher, const void *data, size_t length) {
hasher_Update(hasher, data, length);
}
void xmr_hasher_final(Hasher * hasher, uint8_t * hash){
void xmr_hasher_final(Hasher *hasher, uint8_t *hash) {
hasher_Final(hasher, hash);
}
void xmr_hasher_copy(Hasher * dst, const Hasher * src){
void xmr_hasher_copy(Hasher *dst, const Hasher *src) {
memcpy(dst, src, sizeof(Hasher));
}
void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length){
void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length) {
uint8_t hash[HASHER_DIGEST_LENGTH];
hasher_Raw(HASHER_SHA3K, data, length, hash);
expand256_modm(r, hash, HASHER_DIGEST_LENGTH);
}
void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length){
void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length) {
ge25519 point2;
uint8_t hash[HASHER_DIGEST_LENGTH];
hasher_Raw(HASHER_SHA3K, data, length, hash);
@ -61,26 +58,30 @@ void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length){
ge25519_mul8(P, &point2);
}
void xmr_derivation_to_scalar(bignum256modm s, const ge25519 * p, uint32_t output_index){
void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p,
uint32_t output_index) {
uint8_t buff[32 + 8];
ge25519_pack(buff, p);
int written = xmr_write_varint(buff + 32, 8, output_index);
xmr_hash_to_scalar(s, buff, 32u + written);
}
void xmr_generate_key_derivation(ge25519 * r, const ge25519 * A, const bignum256modm b){
void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A,
const bignum256modm b) {
ge25519 bA;
ge25519_scalarmult(&bA, A, b);
ge25519_mul8(r, &bA);
}
void xmr_derive_private_key(bignum256modm s, const ge25519 * deriv, uint32_t idx, const bignum256modm base){
void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx,
const bignum256modm base) {
xmr_derivation_to_scalar(s, deriv, idx);
add256_modm(s, s, base);
}
void xmr_derive_public_key(ge25519 * r, const ge25519 * deriv, uint32_t idx, const ge25519 * base){
bignum256modm s={0};
void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx,
const ge25519 *base) {
bignum256modm s = {0};
ge25519 p2;
xmr_derivation_to_scalar(s, deriv, idx);
@ -88,7 +89,8 @@ void xmr_derive_public_key(ge25519 * r, const ge25519 * deriv, uint32_t idx, con
ge25519_add(r, base, &p2, 0);
}
void xmr_add_keys2(ge25519 * r, const bignum256modm a, const bignum256modm b, const ge25519 * B){
void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b,
const ge25519 *B) {
// aG + bB, G is basepoint
ge25519 aG, bB;
ge25519_scalarmult_base_niels(&aG, ge25519_niels_base_multiples, a);
@ -96,12 +98,14 @@ void xmr_add_keys2(ge25519 * r, const bignum256modm a, const bignum256modm b, co
ge25519_add(r, &aG, &bB, 0);
}
void xmr_add_keys2_vartime(ge25519 * r, const bignum256modm a, const bignum256modm b, const ge25519 * B){
void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a,
const bignum256modm b, const ge25519 *B) {
// aG + bB, G is basepoint
ge25519_double_scalarmult_vartime(r, B, b, a);
}
void xmr_add_keys3(ge25519 * r, const bignum256modm a, const ge25519 * A, const bignum256modm b, const ge25519 * B){
void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A,
const bignum256modm b, const ge25519 *B) {
// aA + bB
ge25519 aA, bB;
ge25519_scalarmult(&aA, A, a);
@ -109,12 +113,14 @@ void xmr_add_keys3(ge25519 * r, const bignum256modm a, const ge25519 * A, const
ge25519_add(r, &aA, &bB, 0);
}
void xmr_add_keys3_vartime(ge25519 * r, const bignum256modm a, const ge25519 * A, const bignum256modm b, const ge25519 * B){
void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A,
const bignum256modm b, const ge25519 *B) {
// aA + bB
ge25519_double_scalarmult_vartime2(r, A, a, B, b);
}
void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, uint32_t minor, const bignum256modm m){
void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major,
uint32_t minor, const bignum256modm m) {
const char prefix[] = "SubAddr";
unsigned char buff[32];
contract256_modm(buff, m);
@ -123,14 +129,15 @@ void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, uint32_t min
memcpy(data, prefix, sizeof(prefix));
memcpy(data + sizeof(prefix), buff, sizeof(buff));
memcpy(data + sizeof(prefix) + sizeof(buff), &major, sizeof(uint32_t));
memcpy(data + sizeof(prefix) + sizeof(buff) + sizeof(uint32_t), &minor, sizeof(uint32_t));
memcpy(data + sizeof(prefix) + sizeof(buff) + sizeof(uint32_t), &minor,
sizeof(uint32_t));
xmr_hash_to_scalar(r, data, sizeof(data));
}
void xmr_gen_c(ge25519 * r, const bignum256modm a, uint64_t amount){
void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount) {
// C = aG + bH
bignum256modm b={0};
bignum256modm b = {0};
set256_modm(b, amount);
xmr_add_keys2(r, a, b, &xmr_h);
}

@ -24,13 +24,13 @@ void ge25519_set_xmr_h(ge25519 *r);
void xmr_random_scalar(bignum256modm m);
/* cn_fast_hash */
void xmr_fast_hash(uint8_t * hash, const void *data, size_t length);
void xmr_fast_hash(uint8_t *hash, const void *data, size_t length);
/* incremental hashing wrappers */
void xmr_hasher_init(Hasher * hasher);
void xmr_hasher_update(Hasher * hasher, const void *data, size_t length);
void xmr_hasher_final(Hasher * hasher, uint8_t * hash);
void xmr_hasher_copy(Hasher * dst, const Hasher * src);
void xmr_hasher_init(Hasher *hasher);
void xmr_hasher_update(Hasher *hasher, const void *data, size_t length);
void xmr_hasher_final(Hasher *hasher, uint8_t *hash);
void xmr_hasher_copy(Hasher *dst, const Hasher *src);
/* H_s(buffer) */
void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length);
@ -39,29 +39,38 @@ void xmr_hash_to_scalar(bignum256modm r, const void *data, size_t length);
void xmr_hash_to_ec(ge25519 *P, const void *data, size_t length);
/* derivation to scalar value */
void xmr_derivation_to_scalar(bignum256modm s, const ge25519 * p, uint32_t output_index);
void xmr_derivation_to_scalar(bignum256modm s, const ge25519 *p,
uint32_t output_index);
/* derivation */
void xmr_generate_key_derivation(ge25519 * r, const ge25519 * A, const bignum256modm b);
void xmr_generate_key_derivation(ge25519 *r, const ge25519 *A,
const bignum256modm b);
/* H_s(derivation || varint(output_index)) + base */
void xmr_derive_private_key(bignum256modm s, const ge25519 * deriv, uint32_t idx, const bignum256modm base);
void xmr_derive_private_key(bignum256modm s, const ge25519 *deriv, uint32_t idx,
const bignum256modm base);
/* H_s(derivation || varint(output_index))G + base */
void xmr_derive_public_key(ge25519 * r, const ge25519 * deriv, uint32_t idx, const ge25519 * base);
void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx,
const ge25519 *base);
/* aG + bB, G is basepoint */
void xmr_add_keys2(ge25519 * r, const bignum256modm a, const bignum256modm b, const ge25519 * B);
void xmr_add_keys2_vartime(ge25519 * r, const bignum256modm a, const bignum256modm b, const ge25519 * B);
void xmr_add_keys2(ge25519 *r, const bignum256modm a, const bignum256modm b,
const ge25519 *B);
void xmr_add_keys2_vartime(ge25519 *r, const bignum256modm a,
const bignum256modm b, const ge25519 *B);
/* aA + bB */
void xmr_add_keys3(ge25519 * r, const bignum256modm a, const ge25519 * A, const bignum256modm b, const ge25519 * B);
void xmr_add_keys3_vartime(ge25519 * r, const bignum256modm a, const ge25519 * A, const bignum256modm b, const ge25519 * B);
void xmr_add_keys3(ge25519 *r, const bignum256modm a, const ge25519 *A,
const bignum256modm b, const ge25519 *B);
void xmr_add_keys3_vartime(ge25519 *r, const bignum256modm a, const ge25519 *A,
const bignum256modm b, const ge25519 *B);
/* subaddress secret */
void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major, uint32_t minor, const bignum256modm m);
void xmr_get_subaddress_secret_key(bignum256modm r, uint32_t major,
uint32_t minor, const bignum256modm m);
/* Generates Pedersen commitment C = aG + bH */
void xmr_gen_c(ge25519 * r, const bignum256modm a, uint64_t amount);
void xmr_gen_c(ge25519 *r, const bignum256modm a, uint64_t amount);
#endif //TREZOR_CRYPTO_XMR_H
#endif // TREZOR_CRYPTO_XMR_H

347
nem.c

@ -26,19 +26,24 @@
#include "base32.h"
#include "ed25519-donna/ed25519-keccak.h"
#include "memzero.h"
#include "ripemd160.h"
#include "sha3.h"
#include "memzero.h"
#define CAN_WRITE(NEEDED) ((ctx->offset + (NEEDED)) <= ctx->size)
#define SERIALIZE_U32(DATA) \
do { if (!nem_write_u32(ctx, (DATA))) return false; } while (0)
do { \
if (!nem_write_u32(ctx, (DATA))) return false; \
} while (0)
#define SERIALIZE_U64(DATA) \
do { if (!nem_write_u64(ctx, (DATA))) return false; } while (0)
do { \
if (!nem_write_u64(ctx, (DATA))) return false; \
} while (0)
#define SERIALIZE_TAGGED(DATA, LENGTH) \
do { if (!nem_write_tagged(ctx, (DATA), (LENGTH))) return false; } while (0)
do { \
if (!nem_write_tagged(ctx, (DATA), (LENGTH))) return false; \
} while (0)
const char *nem_network_name(uint8_t network) {
switch (network) {
@ -53,7 +58,8 @@ const char *nem_network_name(uint8_t network) {
}
}
static inline bool nem_write_checked(nem_transaction_ctx *ctx, const uint8_t *data, uint32_t length) {
static inline bool nem_write_checked(nem_transaction_ctx *ctx,
const uint8_t *data, uint32_t length) {
if (!CAN_WRITE(length)) {
return false;
}
@ -83,38 +89,45 @@ static inline bool nem_write_u64(nem_transaction_ctx *ctx, uint64_t data) {
return true;
}
static inline bool nem_write_tagged(nem_transaction_ctx *ctx, const uint8_t *data, uint32_t length) {
static inline bool nem_write_tagged(nem_transaction_ctx *ctx,
const uint8_t *data, uint32_t length) {
SERIALIZE_U32(length);
return nem_write_checked(ctx, data, length);
}
static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx, const char *name, const char *value) {
static inline bool nem_write_mosaic_str(nem_transaction_ctx *ctx,
const char *name, const char *value) {
uint32_t name_length = strlen(name);
uint32_t value_length = strlen(value);
SERIALIZE_U32(sizeof(uint32_t) + name_length + sizeof(uint32_t) + value_length);
SERIALIZE_TAGGED((const uint8_t *) name, name_length);
SERIALIZE_TAGGED((const uint8_t *) value, value_length);
SERIALIZE_U32(sizeof(uint32_t) + name_length + sizeof(uint32_t) +
value_length);
SERIALIZE_TAGGED((const uint8_t *)name, name_length);
SERIALIZE_TAGGED((const uint8_t *)value, value_length);
return true;
}
static inline bool nem_write_mosaic_bool(nem_transaction_ctx *ctx, const char *name, bool value) {
static inline bool nem_write_mosaic_bool(nem_transaction_ctx *ctx,
const char *name, bool value) {
return nem_write_mosaic_str(ctx, name, value ? "true" : "false");
}
static inline bool nem_write_mosaic_u64(nem_transaction_ctx *ctx, const char *name, uint64_t value) {
static inline bool nem_write_mosaic_u64(nem_transaction_ctx *ctx,
const char *name, uint64_t value) {
char buffer[21];
if (bn_format_uint64(value, NULL, NULL, 0, 0, false, buffer, sizeof(buffer)) == 0) {
if (bn_format_uint64(value, NULL, NULL, 0, 0, false, buffer,
sizeof(buffer)) == 0) {
return false;
}
return nem_write_mosaic_str(ctx, name, buffer);
}
void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t *address) {
void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version,
uint8_t *address) {
uint8_t hash[SHA3_256_DIGEST_LENGTH];
/* 1. Perform 256-bit Sha3 on the public key */
@ -126,7 +139,8 @@ void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, u
/* 3. Prepend version byte to Ripemd hash (either 0x68 or 0x98) */
address[0] = version;
/* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a checksum */
/* 4. Perform 256-bit Sha3 on the result, take the first four bytes as a
* checksum */
keccak_256(address, 1 + RIPEMD160_DIGEST_LENGTH, hash);
/* 5. Concatenate output of step 3 and the checksum from step 4 */
@ -135,12 +149,14 @@ void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, u
memzero(hash, sizeof(hash));
}
bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char *address) {
bool nem_get_address(const ed25519_public_key public_key, uint8_t version,
char *address) {
uint8_t pubkeyhash[NEM_ADDRESS_SIZE_RAW];
nem_get_address_raw(public_key, version, pubkeyhash);
char *ret = base32_encode(pubkeyhash, sizeof(pubkeyhash), address, NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648);
char *ret = base32_encode(pubkeyhash, sizeof(pubkeyhash), address,
NEM_ADDRESS_SIZE + 1, BASE32_ALPHABET_RFC4648);
memzero(pubkeyhash, sizeof(pubkeyhash));
return (ret != NULL);
@ -167,14 +183,17 @@ bool nem_validate_address(const char *address, uint8_t network) {
return false;
}
uint8_t *ret = base32_decode(address, NEM_ADDRESS_SIZE, pubkeyhash, sizeof(pubkeyhash), BASE32_ALPHABET_RFC4648);
uint8_t *ret = base32_decode(address, NEM_ADDRESS_SIZE, pubkeyhash,
sizeof(pubkeyhash), BASE32_ALPHABET_RFC4648);
bool valid = (ret != NULL) && nem_validate_address_raw(pubkeyhash, network);
memzero(pubkeyhash, sizeof(pubkeyhash));
return valid;
}
void nem_transaction_start(nem_transaction_ctx *ctx, const ed25519_public_key public_key, uint8_t *buffer, size_t size) {
void nem_transaction_start(nem_transaction_ctx *ctx,
const ed25519_public_key public_key, uint8_t *buffer,
size_t size) {
memcpy(ctx->public_key, public_key, sizeof(ctx->public_key));
ctx->buffer = buffer;
@ -182,22 +201,21 @@ void nem_transaction_start(nem_transaction_ctx *ctx, const ed25519_public_key pu
ctx->size = size;
}
size_t nem_transaction_end(nem_transaction_ctx *ctx, const ed25519_secret_key private_key, ed25519_signature signature) {
size_t nem_transaction_end(nem_transaction_ctx *ctx,
const ed25519_secret_key private_key,
ed25519_signature signature) {
if (private_key != NULL && signature != NULL) {
ed25519_sign_keccak(ctx->buffer, ctx->offset, private_key, ctx->public_key, signature);
ed25519_sign_keccak(ctx->buffer, ctx->offset, private_key, ctx->public_key,
signature);
}
return ctx->offset;
}
bool nem_transaction_write_common(nem_transaction_ctx *ctx,
uint32_t type,
uint32_t version,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
bool nem_transaction_write_common(nem_transaction_ctx *ctx, uint32_t type,
uint32_t version, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee,
uint32_t deadline) {
SERIALIZE_U32(type);
SERIALIZE_U32(version);
SERIALIZE_U32(timestamp);
@ -208,19 +226,13 @@ bool nem_transaction_write_common(nem_transaction_ctx *ctx,
return true;
}
bool nem_transaction_create_transfer(nem_transaction_ctx *ctx,
uint8_t network,
bool nem_transaction_create_transfer(nem_transaction_ctx *ctx, uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *recipient,
uint64_t amount,
const uint8_t *payload,
uint32_t length,
bool encrypted,
uint32_t mosaics) {
uint64_t fee, uint32_t deadline,
const char *recipient, uint64_t amount,
const uint8_t *payload, uint32_t length,
bool encrypted, uint32_t mosaics) {
if (!signer) {
signer = ctx->public_key;
}
@ -229,16 +241,13 @@ bool nem_transaction_create_transfer(nem_transaction_ctx *ctx,
length = 0;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_TRANSFER,
(uint32_t) network << 24 | (mosaics ? 2 : 1),
timestamp,
signer,
fee,
deadline);
bool ret =
nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_TRANSFER,
(uint32_t)network << 24 | (mosaics ? 2 : 1),
timestamp, signer, fee, deadline);
if (!ret) return false;
SERIALIZE_TAGGED((const uint8_t *) recipient, NEM_ADDRESS_SIZE);
SERIALIZE_TAGGED((const uint8_t *)recipient, NEM_ADDRESS_SIZE);
SERIALIZE_U64(amount);
if (length) {
@ -250,51 +259,41 @@ bool nem_transaction_create_transfer(nem_transaction_ctx *ctx,
}
if (mosaics) {
SERIALIZE_U32(mosaics);
}
return true;
}
bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx,
const char *namespace,
const char *mosaic,
const char *namespace, const char *mosaic,
uint64_t quantity) {
size_t namespace_length = strlen(namespace);
size_t mosaic_length = strlen(mosaic);
size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
size_t identifier_length =
sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint64_t) + identifier_length);
SERIALIZE_U32(identifier_length);
SERIALIZE_TAGGED((const uint8_t *) namespace, namespace_length);
SERIALIZE_TAGGED((const uint8_t *) mosaic, mosaic_length);
SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length);
SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length);
SERIALIZE_U64(quantity);
return true;
}
bool nem_transaction_create_multisig(nem_transaction_ctx *ctx,
uint8_t network,
bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
uint64_t fee, uint32_t deadline,
const nem_transaction_ctx *inner) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_MULTISIG,
(uint32_t) network << 24 | 1,
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_MULTISIG,
(uint32_t)network << 24 | 1,
timestamp, signer, fee, deadline);
if (!ret) return false;
SERIALIZE_TAGGED(inner->buffer, inner->offset);
@ -302,25 +301,17 @@ bool nem_transaction_create_multisig(nem_transaction_ctx *ctx,
return true;
}
bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
bool nem_transaction_create_multisig_signature(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const nem_transaction_ctx *inner) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE,
(uint32_t) network << 24 | 1,
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(
ctx, NEM_TRANSACTION_TYPE_MULTISIG_SIGNATURE, (uint32_t)network << 24 | 1,
timestamp, signer, fee, deadline);
if (!ret) return false;
char address[NEM_ADDRESS_SIZE + 1];
@ -331,87 +322,61 @@ bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx,
SERIALIZE_U32(sizeof(uint32_t) + SHA3_256_DIGEST_LENGTH);
SERIALIZE_TAGGED(hash, SHA3_256_DIGEST_LENGTH);
SERIALIZE_TAGGED((const uint8_t *) address, NEM_ADDRESS_SIZE);
SERIALIZE_TAGGED((const uint8_t *)address, NEM_ADDRESS_SIZE);
return true;
}
bool nem_transaction_create_provision_namespace(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *namespace,
const char *parent,
const char *rental_sink,
bool nem_transaction_create_provision_namespace(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const char *namespace, const char *parent, const char *rental_sink,
uint64_t rental_fee) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE,
(uint32_t) network << 24 | 1,
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(
ctx, NEM_TRANSACTION_TYPE_PROVISION_NAMESPACE,
(uint32_t)network << 24 | 1, timestamp, signer, fee, deadline);
if (!ret) return false;
if (parent) {
SERIALIZE_TAGGED((const uint8_t *) rental_sink, NEM_ADDRESS_SIZE);
SERIALIZE_TAGGED((const uint8_t *)rental_sink, NEM_ADDRESS_SIZE);
SERIALIZE_U64(rental_fee);
SERIALIZE_TAGGED((const uint8_t *) namespace, strlen(namespace));
SERIALIZE_TAGGED((const uint8_t *) parent, strlen(parent));
SERIALIZE_TAGGED((const uint8_t *)namespace, strlen(namespace));
SERIALIZE_TAGGED((const uint8_t *)parent, strlen(parent));
} else {
SERIALIZE_TAGGED((const uint8_t *) rental_sink, NEM_ADDRESS_SIZE);
SERIALIZE_TAGGED((const uint8_t *)rental_sink, NEM_ADDRESS_SIZE);
SERIALIZE_U64(rental_fee);
SERIALIZE_TAGGED((const uint8_t *) namespace, strlen(namespace));
SERIALIZE_TAGGED((const uint8_t *)namespace, strlen(namespace));
SERIALIZE_U32(0xffffffff);
}
return true;
}
bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *namespace,
const char *mosaic,
const char *description,
uint32_t divisibility,
uint64_t supply,
bool mutable_supply,
bool transferable,
uint32_t levy_type,
uint64_t levy_fee,
const char *levy_address,
const char *levy_namespace,
const char *levy_mosaic,
const char *creation_sink,
uint64_t creation_fee) {
bool nem_transaction_create_mosaic_creation(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const char *namespace, const char *mosaic, const char *description,
uint32_t divisibility, uint64_t supply, bool mutable_supply,
bool transferable, uint32_t levy_type, uint64_t levy_fee,
const char *levy_address, const char *levy_namespace,
const char *levy_mosaic, const char *creation_sink, uint64_t creation_fee) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_MOSAIC_CREATION,
(uint32_t) network << 24 | 1,
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(
ctx, NEM_TRANSACTION_TYPE_MOSAIC_CREATION, (uint32_t)network << 24 | 1,
timestamp, signer, fee, deadline);
if (!ret) return false;
size_t namespace_length = strlen(namespace);
size_t mosaic_length = strlen(mosaic);
size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
size_t identifier_length =
sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
// This length will be rewritten later on
nem_transaction_ctx state;
@ -420,27 +385,30 @@ bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
SERIALIZE_U32(0);
SERIALIZE_TAGGED(signer, sizeof(ed25519_public_key));
SERIALIZE_U32(identifier_length);
SERIALIZE_TAGGED((const uint8_t *) namespace, namespace_length);
SERIALIZE_TAGGED((const uint8_t *) mosaic, mosaic_length);
SERIALIZE_TAGGED((const uint8_t *) description, strlen(description));
SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length);
SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length);
SERIALIZE_TAGGED((const uint8_t *)description, strlen(description));
SERIALIZE_U32(4); // Number of properties
if (!nem_write_mosaic_u64(ctx, "divisibility", divisibility)) return false;
if (!nem_write_mosaic_u64(ctx, "initialSupply", supply)) return false;
if (!nem_write_mosaic_bool(ctx, "supplyMutable", mutable_supply)) return false;
if (!nem_write_mosaic_bool(ctx, "supplyMutable", mutable_supply))
return false;
if (!nem_write_mosaic_bool(ctx, "transferable", transferable)) return false;
if (levy_type) {
size_t levy_namespace_length = strlen(levy_namespace);
size_t levy_mosaic_length = strlen(levy_mosaic);
size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length + sizeof(uint32_t) + levy_mosaic_length;
size_t levy_identifier_length = sizeof(uint32_t) + levy_namespace_length +
sizeof(uint32_t) + levy_mosaic_length;
SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE + sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t));
SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + NEM_ADDRESS_SIZE +
sizeof(uint32_t) + levy_identifier_length + sizeof(uint64_t));
SERIALIZE_U32(levy_type);
SERIALIZE_TAGGED((const uint8_t *) levy_address, NEM_ADDRESS_SIZE);
SERIALIZE_TAGGED((const uint8_t *)levy_address, NEM_ADDRESS_SIZE);
SERIALIZE_U32(levy_identifier_length);
SERIALIZE_TAGGED((const uint8_t *) levy_namespace, levy_namespace_length);
SERIALIZE_TAGGED((const uint8_t *) levy_mosaic, levy_mosaic_length);
SERIALIZE_TAGGED((const uint8_t *)levy_namespace, levy_namespace_length);
SERIALIZE_TAGGED((const uint8_t *)levy_mosaic, levy_mosaic_length);
SERIALIZE_U64(levy_fee);
} else {
SERIALIZE_U32(0);
@ -449,70 +417,51 @@ bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
// Rewrite length
nem_write_u32(&state, ctx->offset - state.offset - sizeof(uint32_t));
SERIALIZE_TAGGED((const uint8_t *) creation_sink, NEM_ADDRESS_SIZE);
SERIALIZE_TAGGED((const uint8_t *)creation_sink, NEM_ADDRESS_SIZE);
SERIALIZE_U64(creation_fee);
return true;
}
bool nem_transaction_create_mosaic_supply_change(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *namespace,
const char *mosaic,
uint32_t type,
uint64_t delta) {
bool nem_transaction_create_mosaic_supply_change(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const char *namespace, const char *mosaic, uint32_t type, uint64_t delta) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE,
(uint32_t) network << 24 | 1,
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(
ctx, NEM_TRANSACTION_TYPE_MOSAIC_SUPPLY_CHANGE,
(uint32_t)network << 24 | 1, timestamp, signer, fee, deadline);
if (!ret) return false;
size_t namespace_length = strlen(namespace);
size_t mosaic_length = strlen(mosaic);
size_t identifier_length = sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
size_t identifier_length =
sizeof(uint32_t) + namespace_length + sizeof(uint32_t) + mosaic_length;
SERIALIZE_U32(identifier_length);
SERIALIZE_TAGGED((const uint8_t *) namespace, namespace_length);
SERIALIZE_TAGGED((const uint8_t *) mosaic, mosaic_length);
SERIALIZE_TAGGED((const uint8_t *)namespace, namespace_length);
SERIALIZE_TAGGED((const uint8_t *)mosaic, mosaic_length);
SERIALIZE_U32(type);
SERIALIZE_U64(delta);
return true;
}
bool nem_transaction_create_aggregate_modification(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
uint32_t modifications,
bool relative_change) {
bool nem_transaction_create_aggregate_modification(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
uint32_t modifications, bool relative_change) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION,
(uint32_t) network << 24 | (relative_change ? 2 : 1),
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(
ctx, NEM_TRANSACTION_TYPE_AGGREGATE_MODIFICATION,
(uint32_t)network << 24 | (relative_change ? 2 : 1), timestamp, signer,
fee, deadline);
if (!ret) return false;
SERIALIZE_U32(modifications);
@ -520,11 +469,11 @@ bool nem_transaction_create_aggregate_modification(nem_transaction_ctx *ctx,
return true;
}
bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx,
uint32_t type,
bool nem_transaction_write_cosignatory_modification(
nem_transaction_ctx *ctx, uint32_t type,
const ed25519_public_key cosignatory) {
SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) + sizeof(ed25519_public_key));
SERIALIZE_U32(sizeof(uint32_t) + sizeof(uint32_t) +
sizeof(ed25519_public_key));
SERIALIZE_U32(type);
SERIALIZE_TAGGED(cosignatory, sizeof(ed25519_public_key));
@ -533,33 +482,23 @@ bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx,
bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx,
int32_t relative_change) {
SERIALIZE_U32(sizeof(uint32_t));
SERIALIZE_U32((uint32_t) relative_change);
SERIALIZE_U32((uint32_t)relative_change);
return true;
}
bool nem_transaction_create_importance_transfer(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
uint32_t mode,
const ed25519_public_key remote) {
bool nem_transaction_create_importance_transfer(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
uint32_t mode, const ed25519_public_key remote) {
if (!signer) {
signer = ctx->public_key;
}
bool ret = nem_transaction_write_common(ctx,
NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER,
(uint32_t) network << 24 | 1,
timestamp,
signer,
fee,
deadline);
bool ret = nem_transaction_write_common(
ctx, NEM_TRANSACTION_TYPE_IMPORTANCE_TRANSFER,
(uint32_t)network << 24 | 1, timestamp, signer, fee, deadline);
if (!ret) return false;
SERIALIZE_U32(mode);

159
nem.h

@ -52,13 +52,17 @@
#define NEM_SALT_SIZE sizeof(ed25519_public_key)
#define NEM_ENCRYPTED_SIZE(size) (((size) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE * AES_BLOCK_SIZE)
#define NEM_ENCRYPTED_PAYLOAD_SIZE(size) (AES_BLOCK_SIZE + NEM_SALT_SIZE + NEM_ENCRYPTED_SIZE(size))
#define NEM_ENCRYPTED_SIZE(size) \
(((size) + AES_BLOCK_SIZE) / AES_BLOCK_SIZE * AES_BLOCK_SIZE)
#define NEM_ENCRYPTED_PAYLOAD_SIZE(size) \
(AES_BLOCK_SIZE + NEM_SALT_SIZE + NEM_ENCRYPTED_SIZE(size))
#define _NEM_PADDING_SIZE(buffer, size) ((buffer)[(size) - 1])
#define NEM_PADDING_SIZE(buffer, size) (_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) : _NEM_PADDING_SIZE(buffer, size))
#define _NEM_PADDING_SIZE(buffer, size) ((buffer)[(size)-1])
#define NEM_PADDING_SIZE(buffer, size) \
(_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) \
: _NEM_PADDING_SIZE(buffer, size))
#define NEM_DECRYPTED_SIZE(buffer, size) ((size) - NEM_PADDING_SIZE(buffer, size))
#define NEM_DECRYPTED_SIZE(buffer, size) ((size)-NEM_PADDING_SIZE(buffer, size))
typedef struct {
ed25519_public_key public_key;
@ -69,123 +73,84 @@ typedef struct {
const char *nem_network_name(uint8_t network);
void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version, uint8_t *address);
bool nem_get_address(const ed25519_public_key public_key, uint8_t version, char *address);
void nem_get_address_raw(const ed25519_public_key public_key, uint8_t version,
uint8_t *address);
bool nem_get_address(const ed25519_public_key public_key, uint8_t version,
char *address);
bool nem_validate_address_raw(const uint8_t *address, uint8_t network);
bool nem_validate_address(const char *address, uint8_t network);
void nem_transaction_start(nem_transaction_ctx *ctx, const ed25519_public_key public_key, uint8_t *buffer, size_t size);
size_t nem_transaction_end(nem_transaction_ctx *ctx, const ed25519_secret_key private_key, ed25519_signature signature);
void nem_transaction_start(nem_transaction_ctx *ctx,
const ed25519_public_key public_key, uint8_t *buffer,
size_t size);
size_t nem_transaction_end(nem_transaction_ctx *ctx,
const ed25519_secret_key private_key,
ed25519_signature signature);
bool nem_transaction_write_common(nem_transaction_ctx *context,
uint32_t type,
uint32_t version,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
bool nem_transaction_write_common(nem_transaction_ctx *context, uint32_t type,
uint32_t version, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee,
uint32_t deadline);
bool nem_transaction_create_transfer(nem_transaction_ctx *context,
uint8_t network,
uint32_t timestamp,
uint8_t network, uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *recipient,
uint64_t amount,
const uint8_t *payload,
uint32_t length,
bool encrypted,
uint32_t mosaics);
uint64_t fee, uint32_t deadline,
const char *recipient, uint64_t amount,
const uint8_t *payload, uint32_t length,
bool encrypted, uint32_t mosaics);
bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx,
const char *namespace,
const char *mosaic,
const char *namespace, const char *mosaic,
uint64_t quantity);
bool nem_transaction_create_multisig(nem_transaction_ctx *ctx,
uint8_t network,
bool nem_transaction_create_multisig(nem_transaction_ctx *ctx, uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
uint64_t fee, uint32_t deadline,
const nem_transaction_ctx *inner);
bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
bool nem_transaction_create_multisig_signature(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const nem_transaction_ctx *inner);
bool nem_transaction_create_provision_namespace(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *namespace,
const char *parent,
const char *rental_sink,
bool nem_transaction_create_provision_namespace(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const char *namespace, const char *parent, const char *rental_sink,
uint64_t rental_fee);
bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *namespace,
const char *mosaic,
const char *description,
uint32_t divisibility,
uint64_t supply,
bool mutable_supply,
bool transferable,
uint32_t levy_type,
uint64_t levy_fee,
const char *levy_address,
const char *levy_namespace,
const char *levy_mosaic,
const char *creation_sink,
uint64_t creation_fee);
bool nem_transaction_create_mosaic_supply_change(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
const char *namespace,
const char *mosaic,
uint32_t type,
uint64_t delta);
bool nem_transaction_create_aggregate_modification(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
uint32_t modifications,
bool relative_change);
bool nem_transaction_write_cosignatory_modification(nem_transaction_ctx *ctx,
uint32_t type,
bool nem_transaction_create_mosaic_creation(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const char *namespace, const char *mosaic, const char *description,
uint32_t divisibility, uint64_t supply, bool mutable_supply,
bool transferable, uint32_t levy_type, uint64_t levy_fee,
const char *levy_address, const char *levy_namespace,
const char *levy_mosaic, const char *creation_sink, uint64_t creation_fee);
bool nem_transaction_create_mosaic_supply_change(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
const char *namespace, const char *mosaic, uint32_t type, uint64_t delta);
bool nem_transaction_create_aggregate_modification(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
uint32_t modifications, bool relative_change);
bool nem_transaction_write_cosignatory_modification(
nem_transaction_ctx *ctx, uint32_t type,
const ed25519_public_key cosignatory);
bool nem_transaction_write_minimum_cosignatories(nem_transaction_ctx *ctx,
int32_t relative_change);
bool nem_transaction_create_importance_transfer(nem_transaction_ctx *ctx,
uint8_t network,
uint32_t timestamp,
const ed25519_public_key signer,
uint64_t fee,
uint32_t deadline,
uint32_t mode,
const ed25519_public_key remote);
bool nem_transaction_create_importance_transfer(
nem_transaction_ctx *ctx, uint8_t network, uint32_t timestamp,
const ed25519_public_key signer, uint64_t fee, uint32_t deadline,
uint32_t mode, const ed25519_public_key remote);
#endif

@ -24,32 +24,35 @@
#include "nist256p1.h"
const ecdsa_curve nist256p1 = {
/* .prime */ {
/*.val =*/ {0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3f, 0x0, 0x0, 0x1000, 0x3fffc000, 0xffff}
},
/* .prime */ {/*.val =*/{0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3f, 0x0, 0x0,
0x1000, 0x3fffc000, 0xffff}},
/* G */ {
/*.x =*/{/*.val =*/{0x1898c296, 0x1284e517, 0x1eb33a0f, 0xdf604b, 0x2440f277, 0x339b958e, 0x4247f8b, 0x347cb84b, 0x6b17}},
/*.y =*/{/*.val =*/{0x37bf51f5, 0x2ed901a0, 0x3315ecec, 0x338cd5da, 0xf9e162b, 0x1fad29f0, 0x27f9b8ee, 0x10b8bf86, 0x4fe3}}
},
/* G */
{/*.x =*/{/*.val =*/{0x1898c296, 0x1284e517, 0x1eb33a0f, 0xdf604b,
0x2440f277, 0x339b958e, 0x4247f8b, 0x347cb84b,
0x6b17}},
/*.y =*/{/*.val =*/{0x37bf51f5, 0x2ed901a0, 0x3315ecec, 0x338cd5da,
0xf9e162b, 0x1fad29f0, 0x27f9b8ee, 0x10b8bf86,
0x4fe3}}},
/* order */ {
/*.val =*/{0x3c632551, 0xee72b0b, 0x3179e84f, 0x39beab69, 0x3fffffbc, 0x3fffffff, 0xfff, 0x3fffc000, 0xffff}
},
/* order */
{/*.val =*/{0x3c632551, 0xee72b0b, 0x3179e84f, 0x39beab69, 0x3fffffbc,
0x3fffffff, 0xfff, 0x3fffc000, 0xffff}},
/* order_half */ {
/*.val =*/{0x3e3192a8, 0x27739585, 0x38bcf427, 0x1cdf55b4, 0x3fffffde, 0x3fffffff, 0x7ff, 0x3fffe000, 0x7fff}
},
/* order_half */
{/*.val =*/{0x3e3192a8, 0x27739585, 0x38bcf427, 0x1cdf55b4, 0x3fffffde,
0x3fffffff, 0x7ff, 0x3fffe000, 0x7fff}},
/* a */ -3,
/* b */ {
/*.val =*/{0x27d2604b, 0x2f38f0f8, 0x53b0f63, 0x741ac33, 0x1886bc65, 0x2ef555da, 0x293e7b3e, 0xd762a8e, 0x5ac6}
}
/* b */
{/*.val =*/{0x27d2604b, 0x2f38f0f8, 0x53b0f63, 0x741ac33, 0x1886bc65,
0x2ef555da, 0x293e7b3e, 0xd762a8e, 0x5ac6}}
#if USE_PRECOMPUTED_CP
,
/* cp */ {
/* cp */
{
#include "nist256p1.table"
}
#endif

@ -26,8 +26,8 @@
#include <stdint.h>
#include "ecdsa.h"
#include "bip32.h"
#include "ecdsa.h"
extern const ecdsa_curve nist256p1;
extern const curve_info nist256p1_info;

@ -21,14 +21,15 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include "pbkdf2.h"
#include <string.h>
#include "hmac.h"
#include "sha2.h"
#include "memzero.h"
#include "sha2.h"
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t blocknr)
{
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass,
int passlen, const uint8_t *salt, int saltlen,
uint32_t blocknr) {
SHA256_CTX ctx;
#if BYTE_ORDER == LITTLE_ENDIAN
REVERSE32(blocknr, blocknr);
@ -39,11 +40,11 @@ void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass,
pctx->g[8] = 0x80000000;
pctx->g[15] = (SHA256_BLOCK_LENGTH + SHA256_DIGEST_LENGTH) * 8;
memcpy (ctx.state, pctx->idig, sizeof(pctx->idig));
memcpy(ctx.state, pctx->idig, sizeof(pctx->idig));
ctx.bitcount = SHA256_BLOCK_LENGTH * 8;
sha256_Update(&ctx, salt, saltlen);
sha256_Update(&ctx, (uint8_t*)&blocknr, sizeof(blocknr));
sha256_Final(&ctx, (uint8_t*)pctx->g);
sha256_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr));
sha256_Final(&ctx, (uint8_t *)pctx->g);
#if BYTE_ORDER == LITTLE_ENDIAN
for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) {
REVERSE32(pctx->g[k], pctx->g[k]);
@ -54,22 +55,21 @@ void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass,
pctx->first = 1;
}
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations)
{
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx,
uint32_t iterations) {
for (uint32_t i = pctx->first; i < iterations; i++) {
sha256_Transform(pctx->idig, pctx->g, pctx->g);
sha256_Transform(pctx->odig, pctx->g, pctx->g);
for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH/sizeof(uint32_t); j++) {
for (uint32_t j = 0; j < SHA256_DIGEST_LENGTH / sizeof(uint32_t); j++) {
pctx->f[j] ^= pctx->g[j];
}
}
pctx->first = 0;
}
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key)
{
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key) {
#if BYTE_ORDER == LITTLE_ENDIAN
for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH/sizeof(uint32_t); k++) {
for (uint32_t k = 0; k < SHA256_DIGEST_LENGTH / sizeof(uint32_t); k++) {
REVERSE32(pctx->f[k], pctx->f[k]);
}
#endif
@ -77,8 +77,9 @@ void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key)
memzero(pctx, sizeof(PBKDF2_HMAC_SHA256_CTX));
}
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen)
{
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt,
int saltlen, uint32_t iterations, uint8_t *key,
int keylen) {
uint32_t last_block_size = keylen % SHA256_DIGEST_LENGTH;
uint32_t blocks_count = keylen / SHA256_DIGEST_LENGTH;
if (last_block_size) {
@ -101,8 +102,9 @@ void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, i
}
}
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t blocknr)
{
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass,
int passlen, const uint8_t *salt, int saltlen,
uint32_t blocknr) {
SHA512_CTX ctx;
#if BYTE_ORDER == LITTLE_ENDIAN
REVERSE32(blocknr, blocknr);
@ -113,12 +115,12 @@ void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass,
pctx->g[8] = 0x8000000000000000;
pctx->g[15] = (SHA512_BLOCK_LENGTH + SHA512_DIGEST_LENGTH) * 8;
memcpy (ctx.state, pctx->idig, sizeof(pctx->idig));
memcpy(ctx.state, pctx->idig, sizeof(pctx->idig));
ctx.bitcount[0] = SHA512_BLOCK_LENGTH * 8;
ctx.bitcount[1] = 0;
sha512_Update(&ctx, salt, saltlen);
sha512_Update(&ctx, (uint8_t*)&blocknr, sizeof(blocknr));
sha512_Final(&ctx, (uint8_t*)pctx->g);
sha512_Update(&ctx, (uint8_t *)&blocknr, sizeof(blocknr));
sha512_Final(&ctx, (uint8_t *)pctx->g);
#if BYTE_ORDER == LITTLE_ENDIAN
for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) {
REVERSE64(pctx->g[k], pctx->g[k]);
@ -129,8 +131,8 @@ void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass,
pctx->first = 1;
}
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations)
{
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx,
uint32_t iterations) {
for (uint32_t i = pctx->first; i < iterations; i++) {
sha512_Transform(pctx->idig, pctx->g, pctx->g);
sha512_Transform(pctx->odig, pctx->g, pctx->g);
@ -141,10 +143,9 @@ void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations
pctx->first = 0;
}
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key)
{
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key) {
#if BYTE_ORDER == LITTLE_ENDIAN
for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH/sizeof(uint64_t); k++) {
for (uint32_t k = 0; k < SHA512_DIGEST_LENGTH / sizeof(uint64_t); k++) {
REVERSE64(pctx->f[k], pctx->f[k]);
}
#endif
@ -152,8 +153,9 @@ void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key)
memzero(pctx, sizeof(PBKDF2_HMAC_SHA512_CTX));
}
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen)
{
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt,
int saltlen, uint32_t iterations, uint8_t *key,
int keylen) {
uint32_t last_block_size = keylen % SHA512_DIGEST_LENGTH;
uint32_t blocks_count = keylen / SHA512_DIGEST_LENGTH;
if (last_block_size) {

@ -43,14 +43,24 @@ typedef struct _PBKDF2_HMAC_SHA512_CTX {
char first;
} PBKDF2_HMAC_SHA512_CTX;
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t blocknr);
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations);
void pbkdf2_hmac_sha256_Init(PBKDF2_HMAC_SHA256_CTX *pctx, const uint8_t *pass,
int passlen, const uint8_t *salt, int saltlen,
uint32_t blocknr);
void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx,
uint32_t iterations);
void pbkdf2_hmac_sha256_Final(PBKDF2_HMAC_SHA256_CTX *pctx, uint8_t *key);
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen);
void pbkdf2_hmac_sha256(const uint8_t *pass, int passlen, const uint8_t *salt,
int saltlen, uint32_t iterations, uint8_t *key,
int keylen);
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t blocknr);
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx, uint32_t iterations);
void pbkdf2_hmac_sha512_Init(PBKDF2_HMAC_SHA512_CTX *pctx, const uint8_t *pass,
int passlen, const uint8_t *salt, int saltlen,
uint32_t blocknr);
void pbkdf2_hmac_sha512_Update(PBKDF2_HMAC_SHA512_CTX *pctx,
uint32_t iterations);
void pbkdf2_hmac_sha512_Final(PBKDF2_HMAC_SHA512_CTX *pctx, uint8_t *key);
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt, int saltlen, uint32_t iterations, uint8_t *key, int keylen);
void pbkdf2_hmac_sha512(const uint8_t *pass, int passlen, const uint8_t *salt,
int saltlen, uint32_t iterations, uint8_t *key,
int keylen);
#endif

@ -25,24 +25,23 @@
#ifndef RAND_PLATFORM_INDEPENDENT
#pragma message("NOT SUITABLE FOR PRODUCTION USE! Replace random32() function with your own secure code.")
#pragma message( \
"NOT SUITABLE FOR PRODUCTION USE! Replace random32() function with your own secure code.")
// The following code is not supposed to be used in a production environment.
// It's included only to make the library testable.
// The message above tries to prevent any accidental use outside of the test environment.
// The message above tries to prevent any accidental use outside of the test
// environment.
//
// You are supposed to replace the random8() and random32() function with your own secure code.
// There is also a possibility to replace the random_buffer() function as it is defined as a weak symbol.
// You are supposed to replace the random8() and random32() function with your
// own secure code. There is also a possibility to replace the random_buffer()
// function as it is defined as a weak symbol.
static uint32_t seed = 0;
void random_reseed(const uint32_t value)
{
seed = value;
}
void random_reseed(const uint32_t value) { seed = value; }
uint32_t random32(void)
{
uint32_t random32(void) {
// Linear congruential generator from Numerical Recipes
// https://en.wikipedia.org/wiki/Linear_congruential_generator
seed = 1664525 * seed + 1013904223;
@ -55,8 +54,7 @@ uint32_t random32(void)
// The following code is platform independent
//
void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len)
{
void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len) {
uint32_t r = 0;
for (size_t i = 0; i < len; i++) {
if (i % 4 == 0) {
@ -66,15 +64,14 @@ void __attribute__((weak)) random_buffer(uint8_t *buf, size_t len)
}
}
uint32_t random_uniform(uint32_t n)
{
uint32_t random_uniform(uint32_t n) {
uint32_t x, max = 0xFFFFFFFF - (0xFFFFFFFF % n);
while ((x = random32()) >= max);
while ((x = random32()) >= max)
;
return x / (max / n);
}
void random_permute(char *str, size_t len)
{
void random_permute(char *str, size_t len) {
for (int i = len - 1; i >= 1; i--) {
int j = random_uniform(i + 1);
char t = str[j];

@ -23,8 +23,8 @@
#ifndef __RC4_H__
#define __RC4_H__
#include <stdint.h>
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint8_t S[256];

@ -22,17 +22,18 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include "rfc6979.h"
#include <string.h>
#include "hmac.h"
#include "memzero.h"
void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *state) {
uint8_t bx[2*32];
uint8_t buf[32 + 1 + 2*32];
void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash,
rfc6979_state *state) {
uint8_t bx[2 * 32];
uint8_t buf[32 + 1 + 2 * 32];
memcpy(bx, priv_key, 32);
memcpy(bx+32, hash, 32);
memcpy(bx + 32, hash, 32);
memset(state->v, 1, sizeof(state->v));
memset(state->k, 0, sizeof(state->k));
@ -54,8 +55,7 @@ void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *s
}
// generate next number from deterministic random number generator
void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state)
{
void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state) {
uint8_t buf[32 + 1];
hmac_sha256(state->k, sizeof(state->k), state->v, sizeof(state->v), state->v);
@ -69,8 +69,7 @@ void generate_rfc6979(uint8_t rnd[32], rfc6979_state *state)
// generate K in a deterministic way, according to RFC6979
// http://tools.ietf.org/html/rfc6979
void generate_k_rfc6979(bignum256 *k, rfc6979_state *state)
{
void generate_k_rfc6979(bignum256 *k, rfc6979_state *state) {
uint8_t buf[32];
generate_rfc6979(buf, state);
bn_read_be(buf, k);

@ -33,7 +33,8 @@ typedef struct {
uint8_t v[32], k[32];
} rfc6979_state;
void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash, rfc6979_state *rng);
void init_rfc6979(const uint8_t *priv_key, const uint8_t *hash,
rfc6979_state *rng);
void generate_rfc6979(uint8_t rnd[32], rfc6979_state *rng);
void generate_k_rfc6979(bignum256 *k, rfc6979_state *rng);

@ -14,7 +14,9 @@ typedef struct _RIPEMD160_CTX {
void ripemd160_Init(RIPEMD160_CTX *ctx);
void ripemd160_Update(RIPEMD160_CTX *ctx, const uint8_t *input, uint32_t ilen);
void ripemd160_Final(RIPEMD160_CTX *ctx, uint8_t output[RIPEMD160_DIGEST_LENGTH]);
void ripemd160(const uint8_t *msg, uint32_t msg_len, uint8_t hash[RIPEMD160_DIGEST_LENGTH]);
void ripemd160_Final(RIPEMD160_CTX *ctx,
uint8_t output[RIPEMD160_DIGEST_LENGTH]);
void ripemd160(const uint8_t *msg, uint32_t msg_len,
uint8_t hash[RIPEMD160_DIGEST_LENGTH]);
#endif

@ -20,23 +20,25 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "script.h"
#include <string.h>
#include "base58.h"
#include "script.h"
int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, int addrsize)
{
int script_output_to_address(const uint8_t *script, int scriptlen, char *addr,
int addrsize) {
uint8_t raw[35];
// P2PKH
if (scriptlen == 25 && script[0] == 0x76 && script[1] == 0xA9 && script[2] == 0x14 && script[23] == 0x88 && script[24] == 0xAC) {
if (scriptlen == 25 && script[0] == 0x76 && script[1] == 0xA9 &&
script[2] == 0x14 && script[23] == 0x88 && script[24] == 0xAC) {
raw[0] = 0x00;
memcpy(raw + 1, script + 3, 20);
return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize);
}
// P2SH
if (scriptlen == 23 && script[0] == 0xA9 && script[1] == 0x14 && script[22] == 0x87) {
if (scriptlen == 23 && script[0] == 0xA9 && script[1] == 0x14 &&
script[22] == 0x87) {
raw[0] = 0x05;
memcpy(raw + 1, script + 2, 20);
return base58_encode_check(raw, 1 + 20, HASHER_SHA2D, addr, addrsize);

@ -25,6 +25,7 @@
#include <stdint.h>
int script_output_to_address(const uint8_t *script, int scriptlen, char *addr, int addrsize);
int script_output_to_address(const uint8_t *script, int scriptlen, char *addr,
int addrsize);
#endif

@ -24,32 +24,33 @@
#include "secp256k1.h"
const ecdsa_curve secp256k1 = {
/* .prime */ {
/*.val =*/ {0x3ffffc2f, 0x3ffffffb, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}
},
/* .prime */ {/*.val =*/{0x3ffffc2f, 0x3ffffffb, 0x3fffffff, 0x3fffffff,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
0xffff}},
/* G */ {
/*.x =*/{/*.val =*/{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb, 0x70b0702, 0x18a573a, 0xbbac55a, 0x199fbe77, 0x79be}},
/*.y =*/{/*.val =*/{0x3b10d4b8, 0x311f423f, 0x28554199, 0x5ed1229, 0x1108a8fd, 0x13eff038, 0x3c4655da, 0x369dc9a8, 0x483a}}
},
/* G */
{/*.x =*/{/*.val =*/{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb,
0x70b0702, 0x18a573a, 0xbbac55a, 0x199fbe77, 0x79be}},
/*.y =*/{/*.val =*/{0x3b10d4b8, 0x311f423f, 0x28554199, 0x5ed1229,
0x1108a8fd, 0x13eff038, 0x3c4655da, 0x369dc9a8,
0x483a}}},
/* order */ {
/*.val =*/{0x10364141, 0x3f497a33, 0x348a03bb, 0x2bb739ab, 0x3ffffeba, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}
},
/* order */
{/*.val =*/{0x10364141, 0x3f497a33, 0x348a03bb, 0x2bb739ab, 0x3ffffeba,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff}},
/* order_half */ {
/*.val =*/{0x281b20a0, 0x3fa4bd19, 0x3a4501dd, 0x15db9cd5, 0x3fffff5d, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x7fff}
},
/* order_half */
{/*.val =*/{0x281b20a0, 0x3fa4bd19, 0x3a4501dd, 0x15db9cd5, 0x3fffff5d,
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x7fff}},
/* a */ 0,
/* b */ {
/*.val =*/{7}
}
/* b */ {/*.val =*/{7}}
#if USE_PRECOMPUTED_CP
,
/* cp */ {
/* cp */
{
#include "secp256k1.table"
}
#endif

@ -26,8 +26,8 @@
#include <stdint.h>
#include "ecdsa.h"
#include "bip32.h"
#include "ecdsa.h"
extern const ecdsa_curve secp256k1;
extern const curve_info secp256k1_info;

@ -35,13 +35,8 @@
* prog_len: Number of data bytes in prog.
* Returns 1 if successful.
*/
int segwit_addr_encode(
char *output,
const char *hrp,
int ver,
const uint8_t *prog,
size_t prog_len
);
int segwit_addr_encode(char *output, const char *hrp, int ver,
const uint8_t *prog, size_t prog_len);
/** Decode a SegWit address
*
@ -49,20 +44,13 @@ int segwit_addr_encode(
* program version (between 0 and 16 inclusive).
* prog: Pointer to a buffer of size 40 that will be updated to
* contain the witness program bytes.
* prog_len: Pointer to a size_t that will be updated to contain the length
* of bytes in prog.
* hrp: Pointer to the null-terminated human readable part that is
* expected (chain/network specific).
* addr: Pointer to the null-terminated address.
* Returns 1 if successful.
* prog_len: Pointer to a size_t that will be updated to contain the
* length of bytes in prog. hrp: Pointer to the null-terminated human
* readable part that is expected (chain/network specific). addr: Pointer to
* the null-terminated address. Returns 1 if successful.
*/
int segwit_addr_decode(
int* ver,
uint8_t* prog,
size_t* prog_len,
const char* hrp,
const char* addr
);
int segwit_addr_decode(int *ver, uint8_t *prog, size_t *prog_len,
const char *hrp, const char *addr);
/** Encode a Bech32 string
*
@ -73,12 +61,8 @@ int segwit_addr_decode(
* data_len: Length of the data array.
* Returns 1 if successful.
*/
int bech32_encode(
char *output,
const char *hrp,
const uint8_t *data,
size_t data_len
);
int bech32_encode(char *output, const char *hrp, const uint8_t *data,
size_t data_len);
/** Decode a Bech32 string
*
@ -91,11 +75,7 @@ int bech32_encode(
* In: input: Pointer to a null-terminated Bech32 string.
* Returns 1 if succesful.
*/
int bech32_decode(
char *hrp,
uint8_t *data,
size_t *data_len,
const char *input
);
int bech32_decode(char *hrp, uint8_t *data, size_t *data_len,
const char *input);
#endif

@ -2,5 +2,5 @@ with import <nixpkgs> {};
stdenv.mkDerivation {
name = "trezor-crypto-dev";
buildInputs = [ gnumake gcc pkgconfig openssl check valgrind ];
buildInputs = [ gnumake gcc pkgconfig openssl check valgrind clang-tools ];
}

File diff suppressed because it is too large Load Diff

@ -1,48 +1,85 @@
// https://github.com/input-output-hk/cardano-crypto/blob/master/tests/goldens/cardano/crypto/wallet/BIP39-128
START_TEST(test_ed25519_cardano_sign_vectors)
{
START_TEST(test_ed25519_cardano_sign_vectors) {
ed25519_public_key public_key;
ed25519_secret_key secret_key;
ed25519_secret_key secret_key_extension;
ed25519_signature signature;
static const char *vectors[] = {
"6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea53", // private key
"60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8e", // private key extension
"64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe1", // public key
"45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c79331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10d", // signature
"e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830c", // private key
"794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a4", // private key extension
"95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931df", // public key
"f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b19ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560f", // signature
"9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0c", // private key
"b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedebb", // private key extension
"79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19f", // public key
"2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800f", // signature
"52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40c", // private key
"6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a25803", // private key extension
"dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d6", // public key
"0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a62a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd781602", // signature
"11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec04", // private key
"c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a5473402352", // private key extension
"839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db78", // public key
"e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa4905", // signature
"5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e505", // private key
"ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098cd", // private key extension
"75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb76", // public key
"631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fbc10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda598906", // signature
"624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50d", // private key
"097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b02", // private key extension
"0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b00", // public key
"1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f901", // signature
0, 0,
static const char
*vectors[] =
{
"6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5"
"3", // private key
"60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8"
"e", // private key extension
"64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe"
"1", // public key
"45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7"
"9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10"
"d", // signature
"e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830"
"c", // private key
"794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a"
"4", // private key extension
"95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d"
"f", // public key
"f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1"
"9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560"
"f", // signature
"9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0"
"c", // private key
"b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb"
"b", // private key extension
"79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19"
"f", // public key
"2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a"
"88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800"
"f", // signature
"52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40"
"c", // private key
"6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580"
"3", // private key extension
"dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d"
"6", // public key
"0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6"
"2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160"
"2", // signature
"11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0"
"4", // private key
"c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235"
"2", // private key extension
"839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7"
"8", // public key
"e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f"
"9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490"
"5", // signature
"5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50"
"5", // private key
"ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c"
"d", // private key extension
"75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7"
"6", // public key
"631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb"
"c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890"
"6", // signature
"624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50"
"d", // private key
"097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0"
"2", // private key extension
"0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0"
"0", // public key
"1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a"
"57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90"
"1", // signature
0,
0,
};
const char **test_data;
@ -59,8 +96,9 @@ START_TEST(test_ed25519_cardano_sign_vectors)
ck_assert_mem_eq(public_key, fromhex(*(test_data + 2)), 32);
const uint8_t * message = (const uint8_t *) "Hello World";
ed25519_sign_ext(message, 11, secret_key, secret_key_extension, public_key, signature);
const uint8_t *message = (const uint8_t *)"Hello World";
ed25519_sign_ext(message, 11, secret_key, secret_key_extension, public_key,
signature);
UNMARK_SECRET_DATA(signature, sizeof(signature));
ck_assert_mem_eq(signature, fromhex(*(test_data + 3)), 64);
@ -73,87 +111,161 @@ START_TEST(test_ed25519_cardano_sign_vectors)
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_1)
{
START_TEST(test_bip32_cardano_hdnode_vector_1) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
ck_assert_mem_eq(node.chain_code, fromhex("affbc325d9027c0f2d9f925b1dcf6c12bf5c1dd08904474066a4f2c00db56173"), 32);
ck_assert_mem_eq(node.private_key, fromhex("08a14df748e477a69d21c97c56db151fc19e2521f31dd0ac5360f269e5b6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("daeb991f2d2128e2525415c56a07f4366baa26c1e48572a5e073934b6de35fbc"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"affbc325d9027c0f2d9f925b1dcf6c12bf5c1dd08904474066a4f2c00db56173"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"08a14df748e477a69d21c97c56db151fc19e2521f31dd0ac5360f269e5b6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"daeb991f2d2128e2525415c56a07f4366baa26c1e48572a5e073934b6de35fbc"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("9a1d04808b4c0682816961cf666e82a7fd35949658aba5354c517eccf12aacb4"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"9a1d04808b4c0682816961cf666e82a7fd35949658aba5354c517eccf12aacb4"),
32);
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_2)
{
START_TEST(test_bip32_cardano_hdnode_vector_2) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
hdnode_private_ckd_cardano(&node, 0x80000000);
ck_assert_mem_eq(node.chain_code, fromhex("104c6a0736e501c9bfe2966ba3773f5320495b19c3f2ed222234850af2ccd5b1"), 32);
ck_assert_mem_eq(node.private_key, fromhex("6064bf06b2e981d7c9792b1482eeecd40ec3cfa12143f4a1f149d48ce8b6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("64aa9a16331f14c981b769efcf96addcc4c6db44047fe7a7feae0be23d33bf54"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"104c6a0736e501c9bfe2966ba3773f5320495b19c3f2ed222234850af2ccd5b1"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"6064bf06b2e981d7c9792b1482eeecd40ec3cfa12143f4a1f149d48ce8b6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"64aa9a16331f14c981b769efcf96addcc4c6db44047fe7a7feae0be23d33bf54"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("c651c14a13c2311fc30a7acf244add1fdac3683e7ba89b4571e4cbcab509b915"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"c651c14a13c2311fc30a7acf244add1fdac3683e7ba89b4571e4cbcab509b915"),
32);
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_3)
{
START_TEST(test_bip32_cardano_hdnode_vector_3) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
hdnode_private_ckd_cardano(&node, 0x80000001);
ck_assert_mem_eq(node.chain_code, fromhex("da99870d7e69de2a76f255ba8c7ed22428c7e5b0a8df978753c707c95ec3d4ca"), 32);
ck_assert_mem_eq(node.private_key, fromhex("c85fa69f4a1891fd98d1d1fc5f0cf9b1d6e44b0e6906744ab23ea766edb6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("b4fc241feffe840b8a54a26ab447f5a5caa31032db3a8091fca14f38b86ed539"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"da99870d7e69de2a76f255ba8c7ed22428c7e5b0a8df978753c707c95ec3d4ca"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"c85fa69f4a1891fd98d1d1fc5f0cf9b1d6e44b0e6906744ab23ea766edb6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"b4fc241feffe840b8a54a26ab447f5a5caa31032db3a8091fca14f38b86ed539"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("5a5b0c92530cd366f05cf072509c806f904262c259e79a0080bbd5ee35706bb1"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"5a5b0c92530cd366f05cf072509c806f904262c259e79a0080bbd5ee35706bb1"),
32);
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_4)
{
START_TEST(test_bip32_cardano_hdnode_vector_4) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
hdnode_private_ckd_cardano(&node, 0x80000000);
hdnode_private_ckd_cardano(&node, 0x80000001);
ck_assert_mem_eq(node.chain_code, fromhex("b40c44dfd9be08591b62be7f9991c85f812d8196927f3c824d9fcb17d275089e"), 32);
ck_assert_mem_eq(node.private_key, fromhex("d064dcf1449d9c3e47f5b422680343561989035bf2e4e23fc34cb61fedb6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("a3071959013af95aaecf78a7a2e1b9838bbbc4864d6a8a2295243782078345cd"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"b40c44dfd9be08591b62be7f9991c85f812d8196927f3c824d9fcb17d275089e"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"d064dcf1449d9c3e47f5b422680343561989035bf2e4e23fc34cb61fedb6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"a3071959013af95aaecf78a7a2e1b9838bbbc4864d6a8a2295243782078345cd"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("aaaca5e7adc69a03ef1f5c017ed02879e8ca871df028461ed9bf19fb8fa15038"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"aaaca5e7adc69a03ef1f5c017ed02879e8ca871df028461ed9bf19fb8fa15038"),
32);
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_5)
{
START_TEST(test_bip32_cardano_hdnode_vector_5) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
@ -161,20 +273,38 @@ START_TEST(test_bip32_cardano_hdnode_vector_5)
hdnode_private_ckd_cardano(&node, 0x80000001);
hdnode_private_ckd_cardano(&node, 0x80000002);
ck_assert_mem_eq(node.chain_code, fromhex("2593896baf92f6ab2c0f253787ab16be0244ba95e0d48ba09da1a7fd3f926c72"), 32);
ck_assert_mem_eq(node.private_key, fromhex("0811b6d5d6f7120cb05d4ce5453d6ce42825c2a8e53b6d370a6b05ccf4b6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("5bebf1eea68acd04932653d944b064b10baaf5886dd73c185cc285059bf93363"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"2593896baf92f6ab2c0f253787ab16be0244ba95e0d48ba09da1a7fd3f926c72"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"0811b6d5d6f7120cb05d4ce5453d6ce42825c2a8e53b6d370a6b05ccf4b6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"5bebf1eea68acd04932653d944b064b10baaf5886dd73c185cc285059bf93363"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("1c87a32c5babad2fe33e0586bdc523574c6126f8368bc76598e17ea46201f980"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"1c87a32c5babad2fe33e0586bdc523574c6126f8368bc76598e17ea46201f980"),
32);
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_6)
{
START_TEST(test_bip32_cardano_hdnode_vector_6) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
@ -183,20 +313,38 @@ START_TEST(test_bip32_cardano_hdnode_vector_6)
hdnode_private_ckd_cardano(&node, 0x80000002);
hdnode_private_ckd_cardano(&node, 0x80000002);
ck_assert_mem_eq(node.chain_code, fromhex("fe8c6c2ab1e30385513fcffb49dcfe3e7805260425ea76b3b72b9f5bbe3b3d40"), 32);
ck_assert_mem_eq(node.private_key, fromhex("6019b9f5ef6ca530b657bcdb500de5455db8d51afb951fa045b6fbb3f6b6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("466332cb097934b43008701e7e27044aa56c7859019e4eba18d91a3bea23dff7"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"fe8c6c2ab1e30385513fcffb49dcfe3e7805260425ea76b3b72b9f5bbe3b3d40"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"6019b9f5ef6ca530b657bcdb500de5455db8d51afb951fa045b6fbb3f6b6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"466332cb097934b43008701e7e27044aa56c7859019e4eba18d91a3bea23dff7"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("0b8f04755481ced76b4e5795aaafdb3cbd757c10fe60e9c58f48cf29a7ec3575"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"0b8f04755481ced76b4e5795aaafdb3cbd757c10fe60e9c58f48cf29a7ec3575"),
32);
}
END_TEST
START_TEST(test_bip32_cardano_hdnode_vector_7)
{
START_TEST(test_bip32_cardano_hdnode_vector_7) {
HDNode node;
uint8_t seed[66];
int seed_len = mnemonic_to_entropy("ring crime symptom enough erupt lady behave ramp apart settle citizen junk", seed);
int seed_len = mnemonic_to_entropy(
"ring crime symptom enough erupt lady behave ramp apart settle citizen "
"junk",
seed);
ck_assert_int_eq(seed_len, 132);
hdnode_from_seed_cardano((const uint8_t *)"", 0, seed, seed_len / 8, &node);
@ -206,10 +354,26 @@ START_TEST(test_bip32_cardano_hdnode_vector_7)
hdnode_private_ckd_cardano(&node, 0x80000002);
hdnode_private_ckd_cardano(&node, 0xBB9ACA00);
ck_assert_mem_eq(node.chain_code, fromhex("ff77c08d37471c1d4cedd3fae2642c009324d9712492efc74dedab09c9bf973c"), 32);
ck_assert_mem_eq(node.private_key, fromhex("488f34840bba516f7920f91676b8681d0dd833b4ce14468e0810b255f9b6ea46"), 32);
ck_assert_mem_eq(node.private_key_extension, fromhex("01eccef768a79859f824a1d3c3e35e131184e2940c3fca9a4c9b307741f65363"), 32);
ck_assert_mem_eq(
node.chain_code,
fromhex(
"ff77c08d37471c1d4cedd3fae2642c009324d9712492efc74dedab09c9bf973c"),
32);
ck_assert_mem_eq(
node.private_key,
fromhex(
"488f34840bba516f7920f91676b8681d0dd833b4ce14468e0810b255f9b6ea46"),
32);
ck_assert_mem_eq(
node.private_key_extension,
fromhex(
"01eccef768a79859f824a1d3c3e35e131184e2940c3fca9a4c9b307741f65363"),
32);
hdnode_fill_public_key(&node);
ck_assert_mem_eq(node.public_key + 1, fromhex("148605be54585773b44ba87e79265149ae444c4cc37cb1f8db8c08482fba293b"), 32);
ck_assert_mem_eq(
node.public_key + 1,
fromhex(
"148605be54585773b44ba87e79265149ae444c4cc37cb1f8db8c08482fba293b"),
32);
}
END_TEST

@ -14,36 +14,23 @@ struct valid_cashaddr_data {
};
static struct valid_cashaddr_data valid_cashaddr[] = {
{
"1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu",
"bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
},
{
"1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR",
"bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
},
{
"16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb",
"bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
},
{
"3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC",
"bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
},
{
"3LDsS579y7sruadqu11beEJoTjdFiFCdX4",
"bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
},
{
"31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw",
"bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"
}
};
{"1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu",
"bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"},
{"1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR",
"bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"},
{"16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb",
"bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"},
{"3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC",
"bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"},
{"3LDsS579y7sruadqu11beEJoTjdFiFCdX4",
"bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"},
{"31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw",
"bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"}};
START_TEST(test_cashaddr)
{
START_TEST(test_cashaddr) {
size_t i;
for (i = 0; i < sizeof(valid_cashchecksum) / sizeof(valid_cashchecksum[0]); ++i) {
for (i = 0; i < sizeof(valid_cashchecksum) / sizeof(valid_cashchecksum[0]);
++i) {
uint8_t data[82];
char rebuild[92];
char hrp[84];
@ -61,16 +48,20 @@ START_TEST(test_cashaddr)
uint8_t rawdata[65];
size_t rawdata_len;
char rebuild[93];
int ret = cash_addr_decode(prog, &prog_len, hrp, valid_cashaddr[i].cashaddress);
int ret =
cash_addr_decode(prog, &prog_len, hrp, valid_cashaddr[i].cashaddress);
ck_assert_int_eq(ret, 1);
ck_assert_int_eq(prog_len, 21);
rawdata_len = base58_decode_check(valid_cashaddr[i].legacy, HASHER_SHA2D, rawdata, sizeof(rawdata));
rawdata_len = base58_decode_check(valid_cashaddr[i].legacy, HASHER_SHA2D,
rawdata, sizeof(rawdata));
ck_assert_int_eq(rawdata_len, 21);
ck_assert_int_eq(prog[0], rawdata[0] == 0 ? 0x00 : rawdata[0] == 5 ? 0x08 : -1);
ck_assert_int_eq(prog[0],
rawdata[0] == 0 ? 0x00 : rawdata[0] == 5 ? 0x08 : -1);
ck_assert_int_eq(memcmp(rawdata + 1, prog + 1, 20), 0);
ret = cash_addr_encode(rebuild, hrp, prog, 21);
ck_assert_int_eq(ret, 1);
ck_assert_int_eq(my_strncasecmp(rebuild, valid_cashaddr[i].cashaddress, 92), 0);
ck_assert_int_eq(my_strncasecmp(rebuild, valid_cashaddr[i].cashaddress, 92),
0);
}
}
END_TEST

@ -1,23 +1,25 @@
#if USE_MONERO
START_TEST(test_xmr_base58)
{
START_TEST(test_xmr_base58) {
static const struct {
uint64_t tag;
char *v1;
char *v2;
} tests[] = {
{0x12,
"3bec484c5d7f0246af520aab550452b5b6013733feabebd681c4a60d457b7fc12d5918e31d3c003da3c778592c07b398ad6f961a67082a75fd49394d51e69bbe",
"43tpGG9PKbwCpjRvNLn1jwXPpnacw2uVUcszAtgmDiVcZK4VgHwjJT9BJz1WGF9eMxSYASp8yNMkuLjeQfWqJn3CNWdWfzV"
},
"3bec484c5d7f0246af520aab550452b5b6013733feabebd681c4a60d457b7fc12d5918e"
"31d3c003da3c778592c07b398ad6f961a67082a75fd49394d51e69bbe",
"43tpGG9PKbwCpjRvNLn1jwXPpnacw2uVUcszAtgmDiVcZK4VgHwjJT9BJz1WGF9eMxSYASp"
"8yNMkuLjeQfWqJn3CNWdWfzV"},
{0x12,
"639050436fa36c8288706771412c5972461578d564188cd7fc6f81d6973d064fa461afe66fb23879936d7225051bebbf7f3ae0c801a90bb99fbb346b2fd4d702",
"45PwgoUKaDHNqLL8o3okzLL7biv7GqPVmd8LTcTrYVrMEKdSYwFcyJfMLSRpfU3nh8Z2m81FJD4sUY3nXCdGe61k1HAp8T1"
},
"639050436fa36c8288706771412c5972461578d564188cd7fc6f81d6973d064fa461afe"
"66fb23879936d7225051bebbf7f3ae0c801a90bb99fbb346b2fd4d702",
"45PwgoUKaDHNqLL8o3okzLL7biv7GqPVmd8LTcTrYVrMEKdSYwFcyJfMLSRpfU3nh8Z2m81"
"FJD4sUY3nXCdGe61k1HAp8T1"},
{53,
"5a10cca900ee47a7f412cd661b29f5ab356d6a1951884593bb170b5ec8b6f2e83b1da411527d062c9fedeb2dad669f2f5585a00a88462b8c95c809a630e5734c",
"9vacMKaj8JJV6MnwDzh2oNVdwTLJfTDyNRiB6NzV9TT7fqvzLivH2dB8Tv7VYR3ncn8vCb3KdNMJzQWrPAF1otYJ9cPKpkr"
},
"5a10cca900ee47a7f412cd661b29f5ab356d6a1951884593bb170b5ec8b6f2e83b1da41"
"1527d062c9fedeb2dad669f2f5585a00a88462b8c95c809a630e5734c",
"9vacMKaj8JJV6MnwDzh2oNVdwTLJfTDyNRiB6NzV9TT7fqvzLivH2dB8Tv7VYR3ncn8vCb3"
"KdNMJzQWrPAF1otYJ9cPKpkr"},
};
uint8_t rawn[512];
@ -32,8 +34,9 @@ START_TEST(test_xmr_base58)
memcpy(rawn, fromhex(raw), len);
r = xmr_base58_addr_encode_check(tests[i].tag, rawn, len, strn, sizeof(strn));
ck_assert_int_eq((size_t) r, strlen(str));
r = xmr_base58_addr_encode_check(tests[i].tag, rawn, len, strn,
sizeof(strn));
ck_assert_int_eq((size_t)r, strlen(str));
ck_assert_mem_eq(strn, str, r);
r = xmr_base58_addr_decode_check(strn, r, &tag, rawn, len);
@ -43,9 +46,7 @@ START_TEST(test_xmr_base58)
}
END_TEST
START_TEST(test_xmr_getset256_modm)
{
START_TEST(test_xmr_getset256_modm) {
static const struct {
uint64_t val;
int r;
@ -87,9 +88,7 @@ START_TEST(test_xmr_getset256_modm)
}
END_TEST
START_TEST(test_xmr_cmp256_modm)
{
START_TEST(test_xmr_cmp256_modm) {
static const struct {
char *a;
char *b;
@ -97,46 +96,30 @@ START_TEST(test_xmr_cmp256_modm)
int res_cmp;
int res_is_zero_a;
} tests[] = {
{
"0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000000",
1, 0, 1
},
{
"0000000000000000000000000000000000000000000000000000000000000000",
"0100000000000000000000000000000000000000000000000000000000000000",
0, -1, 1
},
{
"dec0adde00000000000000000000000000000000000000000000000000000000",
"dec0adde00000000000000000000000000000000000000000000000000000000",
1, 0, 0
},
{
"863346d8863c461cde2ec7c2759352c2b952228f33a86ca06bb79574bbe5c30d",
"3ddbd65a6d3ba5e2ab120603685a353a27ce3fd21dfdbea7952d2dd26f1ca00a",
0, 1, 0
},
{
"f7667f392edbea6e224b1aa9fbf2a3b238b4f977fb4a8f39130cc45f49b5c40a",
"b41b9b1e7e80be71cf290ed4bded58924086b8ac6bdfa1faa0c80c255f074d07",
0, 1, 0
},
{
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27501",
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504",
0, -1, 0
},
{
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504",
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504",
1, 0, 0
},
{
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504",
"0e4005c7826de8f9978749903f41efd140e4ae6d3bed09e558fcce8367b27504",
0, -1, 0
},
{"0000000000000000000000000000000000000000000000000000000000000000",
"0000000000000000000000000000000000000000000000000000000000000000", 1, 0,
1},
{"0000000000000000000000000000000000000000000000000000000000000000",
"0100000000000000000000000000000000000000000000000000000000000000", 0,
-1, 1},
{"dec0adde00000000000000000000000000000000000000000000000000000000",
"dec0adde00000000000000000000000000000000000000000000000000000000", 1, 0,
0},
{"863346d8863c461cde2ec7c2759352c2b952228f33a86ca06bb79574bbe5c30d",
"3ddbd65a6d3ba5e2ab120603685a353a27ce3fd21dfdbea7952d2dd26f1ca00a", 0, 1,
0},
{"f7667f392edbea6e224b1aa9fbf2a3b238b4f977fb4a8f39130cc45f49b5c40a",
"b41b9b1e7e80be71cf290ed4bded58924086b8ac6bdfa1faa0c80c255f074d07", 0, 1,
0},
{"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27501",
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504", 0,
-1, 0},
{"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504",
"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504", 1, 0,
0},
{"0e4005c7826de8f9978749903f40efd140e4ae6d3bed09e558fcce8367b27504",
"0e4005c7826de8f9978749903f41efd140e4ae6d3bed09e558fcce8367b27504", 0,
-1, 0},
};
bignum256modm a1 = {0}, a2 = {0};
@ -152,23 +135,16 @@ START_TEST(test_xmr_cmp256_modm)
}
END_TEST
START_TEST(test_xmr_copy_check_modm)
{
START_TEST(test_xmr_copy_check_modm) {
static const struct {
int check;
char *a;
} tests[] = {
{0,
"0000000000000000000000000000000000000000000000000000000000000000"},
{1,
"ffffff7f00000000000000000000000000000000000000000000000000000000"},
{1,
"ffffffffffffff7f000000000000000000000000000000000000000000000000"},
{1,
"dec0adde00000000000000000000000000000000000000000000000000000000"},
{0,
"dec0adde000000000000000000000fffffffffffffffffffffffffffffffffff"},
{0, "0000000000000000000000000000000000000000000000000000000000000000"},
{1, "ffffff7f00000000000000000000000000000000000000000000000000000000"},
{1, "ffffffffffffff7f000000000000000000000000000000000000000000000000"},
{1, "dec0adde00000000000000000000000000000000000000000000000000000000"},
{0, "dec0adde000000000000000000000fffffffffffffffffffffffffffffffffff"},
};
bignum256modm a1 = {0}, a2 = {0};
@ -179,13 +155,10 @@ START_TEST(test_xmr_copy_check_modm)
ck_assert_int_eq(eq256_modm(a1, a2), 1);
ck_assert_int_eq(check256_modm(a1), tests[i].check);
}
}
END_TEST
START_TEST(test_xmr_mulsub256_modm)
{
START_TEST(test_xmr_mulsub256_modm) {
static const struct {
char *a;
char *b;
@ -225,9 +198,7 @@ START_TEST(test_xmr_mulsub256_modm)
}
END_TEST
START_TEST(test_xmr_muladd256_modm)
{
START_TEST(test_xmr_muladd256_modm) {
static const struct {
char *a;
char *b;
@ -264,21 +235,16 @@ START_TEST(test_xmr_muladd256_modm)
muladd256_modm(r2, a, b, c);
ck_assert_int_eq(eq256_modm(r, r2), 1);
}
}
END_TEST
START_TEST(test_xmr_curve25519_set)
{
START_TEST(test_xmr_curve25519_set) {
static const struct {
uint32_t val;
char *a;
} tests[] = {
{0x0,
"0000000000000000000000000000000000000000000000000000000000000000"},
{0x1,
"0100000000000000000000000000000000000000000000000000000000000000"},
{0x0, "0000000000000000000000000000000000000000000000000000000000000000"},
{0x1, "0100000000000000000000000000000000000000000000000000000000000000"},
{0xdeadc0deUL,
"dec0adde00000000000000000000000000000000000000000000000000000000"},
};
@ -294,12 +260,11 @@ START_TEST(test_xmr_curve25519_set)
}
END_TEST
START_TEST(test_xmr_curve25519_consts)
{
START_TEST(test_xmr_curve25519_consts) {
char *d = "a3785913ca4deb75abd841414d0a700098e879777940c78c73fe6f2bee6c0352";
char *d2 = "59f1b226949bd6eb56b183829a14e00030d1f3eef2808e19e7fcdf56dcd90624";
char *sqrtneg1 = "b0a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b";
char *sqrtneg1 =
"b0a00e4a271beec478e42fad0618432fa7d7fb3d99004d2b0bdfc14f8024832b";
unsigned char buff[32];
bignum25519 a = {0};
@ -318,9 +283,7 @@ START_TEST(test_xmr_curve25519_consts)
}
END_TEST
START_TEST(test_xmr_curve25519_tests)
{
START_TEST(test_xmr_curve25519_tests) {
static const struct {
char *a;
int res_neg;
@ -328,23 +291,28 @@ START_TEST(test_xmr_curve25519_tests)
} tests[] = {
{
"0000000000000000000000000000000000000000000000000000000000000000",
0, 0,
0,
0,
},
{
"0100000000000000000000000000000000000000000000000000000000000000",
1, 1,
1,
1,
},
{
"05737aa6100ee54283dc0d483b8e39e61846f6b3736908243d0c824d250b3139",
1, 1,
1,
1,
},
{
"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15",
1, 1,
1,
1,
},
{
"02587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15",
0, 1,
0,
1,
},
};
@ -358,29 +326,19 @@ START_TEST(test_xmr_curve25519_tests)
}
END_TEST
START_TEST(test_xmr_curve25519_expand_reduce)
{
START_TEST(test_xmr_curve25519_expand_reduce) {
static const struct {
char *a;
char *b;
} tests[] = {
{
"dec0adde00000000000000000000000000000000000000000000000000000000",
"dec0adde00000000000000000000000000000000000000000000000000000000"
},
{
"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15",
"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15"
},
{
"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bcff",
"a8587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc7f"
},
{
"95587a5ef6900fa8e32d6affbd8090b1e33e694284323fffff02d69865f2bcff",
"a8587a5ef6900fa8e32d6affbd8090b1e33e694284323fffff02d69865f2bc7f"
},
{"dec0adde00000000000000000000000000000000000000000000000000000000",
"dec0adde00000000000000000000000000000000000000000000000000000000"},
{"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15",
"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc15"},
{"95587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bcff",
"a8587a5ef6900fa8e32d6a41bd8090b1e33e694284323d1d1f02d69865f2bc7f"},
{"95587a5ef6900fa8e32d6affbd8090b1e33e694284323fffff02d69865f2bcff",
"a8587a5ef6900fa8e32d6affbd8090b1e33e694284323fffff02d69865f2bc7f"},
};
unsigned char buff[32];
@ -391,15 +349,13 @@ START_TEST(test_xmr_curve25519_expand_reduce)
curve25519_contract(buff, a);
ck_assert_mem_eq(buff, fromhex(tests[i].b), 32);
}
}
END_TEST
START_TEST(test_xmr_ge25519_base)
{
START_TEST(test_xmr_ge25519_base) {
unsigned char buff[32];
char *base = "5866666666666666666666666666666666666666666666666666666666666666";
char *base =
"5866666666666666666666666666666666666666666666666666666666666666";
ge25519 b;
ge25519_set_base(&b);
ge25519_pack(buff, &b);
@ -407,9 +363,7 @@ START_TEST(test_xmr_ge25519_base)
}
END_TEST
START_TEST(test_xmr_ge25519_check)
{
START_TEST(test_xmr_ge25519_check) {
static const struct {
char *x;
char *y;
@ -417,36 +371,26 @@ START_TEST(test_xmr_ge25519_check)
char *t;
int r;
} tests[] = {
{
"4ff97748221f954414f836d84e8e7e207786bcd20eb67044756dca307e792c60",
{"4ff97748221f954414f836d84e8e7e207786bcd20eb67044756dca307e792c60",
"2c7be86ab07488ba43e8e03d85a67625cfbf98c8544de4c877241b7aaafc7f63",
"0100000000000000000000000000000000000000000000000000000000000000",
"3ec65b03954ce7432525b9b3f4a9f5747f57b40903d1bf8892527366325fe036", 1
},
{
"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c",
"3ec65b03954ce7432525b9b3f4a9f5747f57b40903d1bf8892527366325fe036", 1},
{"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c",
"ca48045f790145a1eec3946dfd73747fde0fdb4238607e0a203f8ef5bef90e0e",
"0100000000000000000000000000000000000000000000000000000000000000",
"6c5e5cbae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 1
},
{
"4ff97748221f954414f836d84e8e7e207786bcd20eb6704475ffca307e792c60",
"6c5e5cbae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 1},
{"4ff97748221f954414f836d84e8e7e207786bcd20eb6704475ffca307e792c60",
"2c7be86ab07488ba43e8e03d85a67625cfbf98c8544de4c877241b7aaafc7f63",
"0100000000000000000000000000000000000000000000000000000000000000",
"3ec65b03954ce7432525b9b3f4a9f5747f57b40903d1bf8892527366325fe036", 0
},
{
"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c",
"3ec65b03954ce7432525b9b3f4a9f5747f57b40903d1bf8892527366325fe036", 0},
{"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c",
"ca48045f790145a1eec3946dfd73747fdfffdb4238607e0a203f8ef5bef90e0e",
"0100000000000000000000000000000000000000000000000000000000000000",
"6c5e5cbae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 0
},
{
"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c",
"6c5e5cbae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 0},
{"358fd25e4b84397d207e23cf3a75819bd6b2254cabc990b31ad63873cc38fc7c",
"ca48045f790145a1eec3946dfd73747fdfffdb4238607e0a203f8ef5bef90e0e",
"0100000000000000000000000000000000000000000000000000000000000000",
"6c5e5ffae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 0
},
"6c5e5ffae4b05e149d0aca50bf7b4112acbbe6233ace9c8bd5bcedf34df9ce0b", 0},
};
struct ge25519_t p;
@ -461,9 +405,7 @@ START_TEST(test_xmr_ge25519_check)
}
END_TEST
START_TEST(test_xmr_ge25519_scalarmult_base_wrapper)
{
START_TEST(test_xmr_ge25519_scalarmult_base_wrapper) {
static const struct {
char *sc;
char *pt;
@ -510,9 +452,7 @@ START_TEST(test_xmr_ge25519_scalarmult_base_wrapper)
}
END_TEST
START_TEST(test_xmr_ge25519_scalarmult)
{
START_TEST(test_xmr_ge25519_scalarmult) {
static const struct {
char *sc;
char *pt;
@ -568,9 +508,7 @@ START_TEST(test_xmr_ge25519_scalarmult)
}
END_TEST
START_TEST(test_xmr_ge25519_ops)
{
START_TEST(test_xmr_ge25519_ops) {
int tests[] = {1, 2, 7, 8, 637, 9912, 12345};
for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) {
struct ge25519_t a, b, c, d;
@ -609,22 +547,29 @@ START_TEST(test_xmr_ge25519_ops)
}
END_TEST
START_TEST(test_xmr_check_point)
{
START_TEST(test_xmr_check_point) {
static const struct {
char *p;
bool on;
} tests[] = {
{"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608", true},
{"54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5", true},
{"bebe3c84092c0f7a92704cafb16562cc45c47f45e84baec8d4bba3559d1c1808", true},
{"00000000000000c60073ec000000000000ff0000000000000000000000000080", false},
{"00000000000000004e0000000000000000000000000000000000000000000000", false},
{"0000008b0000000000000000b200000000000000000000000000000000000080", false},
{"a0953eebe2f676256c37af4f6f84f32d397aaf3b73606e96c5ddfcecbb1ceec8", false},
{"a82cd837efee505ec8425769ea925bee869ec3c78a57708c64c2ef2bd6ad3b88", false},
{"031c56cfc99758f6f025630e77c6dea0b853c3ab0bf6cf8c8dab03d1a4618178", false},
{"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608",
true},
{"54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5",
true},
{"bebe3c84092c0f7a92704cafb16562cc45c47f45e84baec8d4bba3559d1c1808",
true},
{"00000000000000c60073ec000000000000ff0000000000000000000000000080",
false},
{"00000000000000004e0000000000000000000000000000000000000000000000",
false},
{"0000008b0000000000000000b200000000000000000000000000000000000080",
false},
{"a0953eebe2f676256c37af4f6f84f32d397aaf3b73606e96c5ddfcecbb1ceec8",
false},
{"a82cd837efee505ec8425769ea925bee869ec3c78a57708c64c2ef2bd6ad3b88",
false},
{"031c56cfc99758f6f025630e77c6dea0b853c3ab0bf6cf8c8dab03d1a4618178",
false},
};
ge25519 tmp;
@ -636,9 +581,7 @@ START_TEST(test_xmr_check_point)
}
END_TEST
START_TEST(test_xmr_h)
{
START_TEST(test_xmr_h) {
char *H = "8b655970153799af2aeadc9ff1add0ea6c7251d54154cfa92c173a0dd39c1f94";
ge25519 H2, Z;
ge25519_p1p1 P_11;
@ -667,19 +610,24 @@ START_TEST(test_xmr_h)
}
END_TEST
START_TEST(test_xmr_fast_hash)
{
START_TEST(test_xmr_fast_hash) {
uint8_t hash[32];
char tests[][2][65] = {
{"", "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"},
{"00", "bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a"},
{"000102", "f84a97f1f0a956e738abd85c2e0a5026f8874e3ec09c8f012159dfeeaab2b156"},
{"000102030405", "51e8babe8b42352100dffa7f7b3843c95245d3d545c6cbf5052e80258ae80627"},
{"000102030406", "74e7a0111ee2390dc68269a549a76dcfb553ca1260035eae982d669ff6494f32"},
{"000102030407", "3a81c5d02a87786343f88414aae150a09f6933b1d3bb660d0a9ac54e12e5cd86"},
{"259ef2aba8feb473cf39058a0fe30b9ff6d245b42b6826687ebd6b63128aff64", "7fb4d1c8e32f7414fe8c7b2774ec05bff6845e4278565d17f95559513a244da2"},
{"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05", "2998fe52f8b9883149babd9c546912c3edfbd3cd98896a0e57b1b5929fa5ff7b"},
{"00",
"bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a"},
{"000102",
"f84a97f1f0a956e738abd85c2e0a5026f8874e3ec09c8f012159dfeeaab2b156"},
{"000102030405",
"51e8babe8b42352100dffa7f7b3843c95245d3d545c6cbf5052e80258ae80627"},
{"000102030406",
"74e7a0111ee2390dc68269a549a76dcfb553ca1260035eae982d669ff6494f32"},
{"000102030407",
"3a81c5d02a87786343f88414aae150a09f6933b1d3bb660d0a9ac54e12e5cd86"},
{"259ef2aba8feb473cf39058a0fe30b9ff6d245b42b6826687ebd6b63128aff64",
"7fb4d1c8e32f7414fe8c7b2774ec05bff6845e4278565d17f95559513a244da2"},
{"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05",
"2998fe52f8b9883149babd9c546912c3edfbd3cd98896a0e57b1b5929fa5ff7b"},
};
for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) {
@ -689,28 +637,28 @@ START_TEST(test_xmr_fast_hash)
}
END_TEST
START_TEST(test_xmr_hasher)
{
START_TEST(test_xmr_hasher) {
Hasher hasher;
uint8_t hash[32];
static const struct {
char * chunk[3];
char * hash;
char *chunk[3];
char *hash;
} tests[] = {
{ {"00", "01", "02"},
{{"00", "01", "02"},
"f84a97f1f0a956e738abd85c2e0a5026f8874e3ec09c8f012159dfeeaab2b156"},
{ {"001122334455667788", "00", ""},
{{"001122334455667788", "00", ""},
"72a228ee8d0d01c815f112ce315cfc215a0594abcec24162304ae0ffda139d9e"},
{ {"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608", "", "00112233445566"},
{{"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608", "",
"00112233445566"},
"c3deafd96ff10cc190c6024548c344f6401cfe5151ab2fcd40df7cc501147e01"},
};
for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) {
xmr_hasher_init(&hasher);
for(int j = 0; j < 3; j++){
xmr_hasher_update(&hasher, fromhex(tests[i].chunk[j]), strlen(tests[i].chunk[j]) / 2);
for (int j = 0; j < 3; j++) {
xmr_hasher_update(&hasher, fromhex(tests[i].chunk[j]),
strlen(tests[i].chunk[j]) / 2);
}
xmr_hasher_final(&hasher, hash);
ck_assert_mem_eq(hash, fromhex(tests[i].hash), 32);
@ -718,20 +666,25 @@ START_TEST(test_xmr_hasher)
}
END_TEST
START_TEST(test_xmr_hash_to_scalar)
{
START_TEST(test_xmr_hash_to_scalar) {
bignum256modm a1;
unsigned char out[32];
char tests[][2][65] = {
{"", "4a078e76cd41a3d3b534b83dc6f2ea2de500b653ca82273b7bfad8045d85a400"},
{"00", "5497c9b6a7059553835f85118dc089d66512f7b477d66591ff96a9e064bcc90a"},
{"000102", "5727ca206dbafa2e099b022ed528f5bdf7874e3ec09c8f012159dfeeaab2b106"},
{"000102030405", "7740cf04577c107153a50b3abe44859f5245d3d545c6cbf5052e80258ae80607"},
{"000102030406", "ad6bbffaceb8020543ac82bcadb9d090b553ca1260035eae982d669ff6494f02"},
{"000102030407", "d2e116e9576ee5a29011c8fcb41259f99e6933b1d3bb660d0a9ac54e12e5cd06"},
{"259ef2aba8feb473cf39058a0fe30b9ff6d245b42b6826687ebd6b63128aff64", "3d6d3727dc50bca39e6ccfc9c12950eef5845e4278565d17f95559513a244d02"},
{"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05", "aecc45c83f0408c96c70f8273e94f930edfbd3cd98896a0e57b1b5929fa5ff0b"},
{"00",
"5497c9b6a7059553835f85118dc089d66512f7b477d66591ff96a9e064bcc90a"},
{"000102",
"5727ca206dbafa2e099b022ed528f5bdf7874e3ec09c8f012159dfeeaab2b106"},
{"000102030405",
"7740cf04577c107153a50b3abe44859f5245d3d545c6cbf5052e80258ae80607"},
{"000102030406",
"ad6bbffaceb8020543ac82bcadb9d090b553ca1260035eae982d669ff6494f02"},
{"000102030407",
"d2e116e9576ee5a29011c8fcb41259f99e6933b1d3bb660d0a9ac54e12e5cd06"},
{"259ef2aba8feb473cf39058a0fe30b9ff6d245b42b6826687ebd6b63128aff64",
"3d6d3727dc50bca39e6ccfc9c12950eef5845e4278565d17f95559513a244d02"},
{"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05",
"aecc45c83f0408c96c70f8273e94f930edfbd3cd98896a0e57b1b5929fa5ff0b"},
};
for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) {
@ -742,20 +695,25 @@ START_TEST(test_xmr_hash_to_scalar)
}
END_TEST
START_TEST(test_xmr_hash_to_ec)
{
START_TEST(test_xmr_hash_to_ec) {
ge25519 p1;
unsigned char out[32];
char tests[][2][65] = {
{"", "d6d7d783ab18e1be65586adb7902a4175b737ef0b902875e1d1d5c5cf0478c0b"},
{"00", "8e2fecb36320bc4e192e10ef54afc7c83fbeb0c38b7debd4fea51301f0bd4f3d"},
{"000102", "73b233e2e75d81b9657a857e38e7ab2bc3600e5c56622b9fe4b976ff312220fa"},
{"000102030405", "bebe3c84092c0f7a92704cafb16562cc45c47f45e84baec8d4bba3559d1c1808"},
{"000102030406", "525567a6a40a94f2d916bc1efea234bbd3b9162403ec2faba871a90f8d0d487e"},
{"000102030407", "99b1be2a92cbd22b24b48fb7a9daadd4d13a56915c4f6ed696f271ad5bdbc149"},
{"42f6835bf83114a1f5f6076fe79bdfa0bd67c74b88f127d54572d3910dd09201", "54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5"},
{"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05", "001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608"},
{"00",
"8e2fecb36320bc4e192e10ef54afc7c83fbeb0c38b7debd4fea51301f0bd4f3d"},
{"000102",
"73b233e2e75d81b9657a857e38e7ab2bc3600e5c56622b9fe4b976ff312220fa"},
{"000102030405",
"bebe3c84092c0f7a92704cafb16562cc45c47f45e84baec8d4bba3559d1c1808"},
{"000102030406",
"525567a6a40a94f2d916bc1efea234bbd3b9162403ec2faba871a90f8d0d487e"},
{"000102030407",
"99b1be2a92cbd22b24b48fb7a9daadd4d13a56915c4f6ed696f271ad5bdbc149"},
{"42f6835bf83114a1f5f6076fe79bdfa0bd67c74b88f127d54572d3910dd09201",
"54863a0464c008acc99cffb179bc6cf34eb1bbdf6c29f7a070a7c6376ae30ab5"},
{"44caa1c26187afe8dacc5d91cb8a51282334d9308a818fe4d3607275e2a61f05",
"001000a93e0e6937b4feaf079e418a028ca85459aa39ac3871b94076f88ca608"},
};
for (size_t i = 0; i < (sizeof(tests) / sizeof(*tests)); i++) {
@ -766,28 +724,30 @@ START_TEST(test_xmr_hash_to_ec)
}
END_TEST
START_TEST(test_xmr_derivation_to_scalar)
{
START_TEST(test_xmr_derivation_to_scalar) {
static const struct {
char *pt;
uint32_t idx;
char *sc;
} tests[] = {
{
"c655b2d9d2670a1c9f26f7586b6d6b1ec5173b8b33bca64c3d305a42d66738b1", 0,
"c655b2d9d2670a1c9f26f7586b6d6b1ec5173b8b33bca64c3d305a42d66738b1",
0,
"ca7ce31b273dd1ac00dc3553e654fb66036804800e27c826bd2b78649243900b",
},
{
"2b1dbd7a007dcc4d729fa8359705595599737fcef60afb36b379fe033095dca7", 1,
"2b1dbd7a007dcc4d729fa8359705595599737fcef60afb36b379fe033095dca7",
1,
"60afd5a63b14845d3b92d16eac386713e4ff617fdc5c1a07c3212098c1f5610c",
},
{
"a48ed3797225dab4b4316b5e40107b6bd63e5f4dc517ba602774d703576ec771", 24,
"a48ed3797225dab4b4316b5e40107b6bd63e5f4dc517ba602774d703576ec771",
24,
"fe81804091e50a5c2233faa6277360fbe1948ea15dddbae62c1d40bbd1918606",
},
{
"fa27b5b39741f5341b4e89269e3a05ff7e76ec7739843872468fc4bec8475410", 65537,
"fa27b5b39741f5341b4e89269e3a05ff7e76ec7739843872468fc4bec8475410",
65537,
"1ba36841f57aa8b799c4dd02b39d53e5fb7780d3f09f91a57a86dcb418d8d506",
},
};
@ -808,9 +768,7 @@ START_TEST(test_xmr_derivation_to_scalar)
}
END_TEST
START_TEST(test_xmr_generate_key_derivation)
{
START_TEST(test_xmr_generate_key_derivation) {
static const struct {
char *pt;
char *sc;
@ -847,9 +805,7 @@ START_TEST(test_xmr_generate_key_derivation)
}
END_TEST
START_TEST(test_xmr_derive_private_key)
{
START_TEST(test_xmr_derive_private_key) {
static const struct {
char *pt;
uint32_t idx;
@ -857,17 +813,20 @@ START_TEST(test_xmr_derive_private_key)
char *r;
} tests[] = {
{
"0541d8f069e5e80a892e39bbf1944ef578008cf9ecf1d100760a05858c1b709e", 0,
"0541d8f069e5e80a892e39bbf1944ef578008cf9ecf1d100760a05858c1b709e",
0,
"76967eeb0a3d181bb0b384be71c680a4287599f27b2ddbd07f8e06ab6f2c880e",
"45728c5cb658e470790f124a01699d2126832b7e5c6b7760b6f11119b96ad603",
},
{
"fc6e0bd785a84e62c9ac8a97e0e604a79494bc2cf7b3b38ef8af7791c87b5bb8", 1,
"fc6e0bd785a84e62c9ac8a97e0e604a79494bc2cf7b3b38ef8af7791c87b5bb8",
1,
"32fbe149562b7ccb34bc4105b87b2a834024799336c8eea5e94df77f1ae9a807",
"64508e83bbadf63f8ecfae4d9dcdd39a4ba23508a545e1a37026f0fa2539d601",
},
{
"f6bd7a72dc9444dc7e09a0eb4d312d36fe173693d6405b132a5b090297a04ea9", 65537,
"f6bd7a72dc9444dc7e09a0eb4d312d36fe173693d6405b132a5b090297a04ea9",
65537,
"333a8fcce6726457e4222a87b9b475c1fcf985f756c2029fcb39184c0a5c4804",
"37c16a22da4c0082ebf4bf807403b169f75142a9bd8560ed45f3f9347218260e",
},
@ -888,9 +847,7 @@ START_TEST(test_xmr_derive_private_key)
}
END_TEST
START_TEST(test_xmr_derive_public_key)
{
START_TEST(test_xmr_derive_public_key) {
static const struct {
char *pt;
uint32_t idx;
@ -898,17 +855,20 @@ START_TEST(test_xmr_derive_public_key)
char *r;
} tests[] = {
{
"653f03e7766d472826aa49793bc0cfde698e6745ae5e4217980ba307739f2ed9", 0,
"653f03e7766d472826aa49793bc0cfde698e6745ae5e4217980ba307739f2ed9",
0,
"2a393f0858732970ac8dea003b17e1ce9371f0a045bd9b7af0d998262739f4cc",
"f7a3db27c45f265f6a68a30137ca44289a6cf1a6db2cf482c59ebfb0142ad419",
},
{
"338e93f61e6470a5cc71c07b8caedd1a9a28da037aab65c1ca5538501b012c81", 1,
"338e93f61e6470a5cc71c07b8caedd1a9a28da037aab65c1ca5538501b012c81",
1,
"af3a1d39397d778731c4510110fd117dc02f756e390713d58f94a06203ce39eb",
"779e2a043c881f06aba1952741fd753098615c4fafa8f62748467ab9bac43241",
},
{
"7735e9476440927b89b18d7a1e0645b218a1a6d28c642aebb16c1dba0926d5e4", 65537,
"7735e9476440927b89b18d7a1e0645b218a1a6d28c642aebb16c1dba0926d5e4",
65537,
"62c3eed062bd602f7f2164c69ad0b5a8eb3ea560c930f6b41abfc1c4839ea432",
"6da4ebd29498d16c4e813abb3e328c83f9b01a7ba1da6e818071f8ec563626c8",
},
@ -929,9 +889,7 @@ START_TEST(test_xmr_derive_public_key)
}
END_TEST
START_TEST(test_xmr_add_keys2)
{
START_TEST(test_xmr_add_keys2) {
static const struct {
char *a;
char *b;
@ -978,9 +936,7 @@ START_TEST(test_xmr_add_keys2)
}
END_TEST
START_TEST(test_xmr_add_keys3)
{
START_TEST(test_xmr_add_keys3) {
static const struct {
char *a;
char *A;
@ -1032,26 +988,27 @@ START_TEST(test_xmr_add_keys3)
}
END_TEST
START_TEST(test_xmr_get_subaddress_secret_key)
{
START_TEST(test_xmr_get_subaddress_secret_key) {
static const struct {
uint32_t major, minor;
char *m;
char *r;
} tests[] = {
{
0, 0,
0,
0,
"36fad9f7bff465c15a755f1482fb2ecc3a4e434303df906882234e42b5813207",
"8a510a9fe1824b49abbae05958084f9c9098775f29e15427309177882471cf01",
},
{
0, 1,
0,
1,
"36fad9f7bff465c15a755f1482fb2ecc3a4e434303df906882234e42b5813207",
"2bbc9366c04abb0523e2b2d6e709670ffe6645bacedfee968d9c6bc8eefe9c0f",
},
{
100, 100,
100,
100,
"36fad9f7bff465c15a755f1482fb2ecc3a4e434303df906882234e42b5813207",
"c3837d41fedeaed126cf4fc1a5ea47b8b7f38f6a64aa534e3dd45a3c93f37600",
},
@ -1070,28 +1027,30 @@ START_TEST(test_xmr_get_subaddress_secret_key)
}
END_TEST
START_TEST(test_xmr_gen_c)
{
START_TEST(test_xmr_gen_c) {
static const struct {
char *a;
uint64_t amount;
char *r;
} tests[] = {
{
"e3e6558c291bbb98aa691d068b67d59dc520afb23fdd51bf65283626fc2ad903", 0,
"e3e6558c291bbb98aa691d068b67d59dc520afb23fdd51bf65283626fc2ad903",
0,
"ef19d73bdf3749240b80ee7695f53ad7c2fc2cf868a93209799f41212d099750",
},
{
"6788c9579c377f3228680bd0e6d01b1ee0c763b35ed39d36fa2146cc2ee16e0e", 1,
"6788c9579c377f3228680bd0e6d01b1ee0c763b35ed39d36fa2146cc2ee16e0e",
1,
"4913b9af4f2725d87a4404c22cf366597d1c1e6a1f510ae14081d8b7c5a9de77",
},
{
"ad9e89d67012935540427c241756d6a9d260c5e134603c41d31e24f8651bef08", 65537,
"ad9e89d67012935540427c241756d6a9d260c5e134603c41d31e24f8651bef08",
65537,
"f005721da08f24e68314abed3ddfd94165e4be3813398fb126e3f366820b9c90",
},
{
"fdbb70ff07be24d98de3bffa0a33756646497224318fb7fe136f0e7789d12607", 0xffffffffffffffffULL,
"fdbb70ff07be24d98de3bffa0a33756646497224318fb7fe136f0e7789d12607",
0xffffffffffffffffULL,
"a9c38927f299c5f14c98a1a9c9981e59c606ff597274b9b709e1356f12e1498c",
},
};
@ -1109,9 +1068,7 @@ START_TEST(test_xmr_gen_c)
}
END_TEST
START_TEST(test_xmr_varint)
{
START_TEST(test_xmr_varint) {
static const struct {
uint64_t x;
char *r;
@ -1158,10 +1115,10 @@ START_TEST(test_xmr_varint)
int written = 0;
int read = 0;
ck_assert_int_eq(s1, strlen(tests[i].r)/2);
ck_assert_int_eq(s1, strlen(tests[i].r) / 2);
written = xmr_write_varint(buff, sizeof(buff), tests[i].x);
ck_assert_int_eq(s1, written);
ck_assert_mem_eq(buff, fromhex(tests[i].r), strlen(tests[i].r)/2);
ck_assert_mem_eq(buff, fromhex(tests[i].r), strlen(tests[i].r) / 2);
read = xmr_read_varint(buff, sizeof(buff), &val);
ck_assert_int_eq(read, written);
@ -1170,9 +1127,7 @@ START_TEST(test_xmr_varint)
}
END_TEST
START_TEST(test_xmr_gen_range_sig)
{
START_TEST(test_xmr_gen_range_sig) {
uint64_t tests[] = {
0, 1, 65535, 65537, 0xffffffffffffffffULL, 0xdeadc0deULL,
};
@ -1187,7 +1142,7 @@ START_TEST(test_xmr_gen_range_sig)
xmr_gen_range_sig(&sig, &C, mask, tests[i], NULL);
ge25519_set_neutral(&Ctmp);
for(int j = 0; j < XMR_ATOMS; j++){
for (int j = 0; j < XMR_ATOMS; j++) {
ge25519_unpack_vartime(&Cb, sig.Ci[j]);
ge25519_add(&Ctmp, &Ctmp, &Cb, 0);
}
@ -1198,7 +1153,7 @@ START_TEST(test_xmr_gen_range_sig)
ge25519_set_xmr_h(&Ch);
expand256_modm(ee, sig.asig.ee, 32);
for(int j = 0; j < XMR_ATOMS; j++){
for (int j = 0; j < XMR_ATOMS; j++) {
ge25519_unpack_vartime(&P1, sig.Ci[j]);
ge25519_add(&P2, &P1, &Ch, 1);
expand256_modm(s, sig.asig.s0[j], 32);

@ -2,16 +2,20 @@
static const char* valid_checksum[] = {
"A12UEL5L",
"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1tt5tgs",
"an83characterlonghumanreadablepartthatcontainsthenumber1andtheexcludedchar"
"actersbio1tt5tgs",
"abcdef1qpzry9x8gf2tvdw0s3jn54khce6mua7lmqqqxw",
"11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqc8247j",
"11qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq"
"qqqqqqqqqqc8247j",
"split1checkupstagehandshakeupstreamerranterredcaperred2y9e3w",
};
static const char* invalid_checksum[] = {
" 1nwldj5",
"\x7f""1axkwrx",
"an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcharactersbio1569pvx",
"\x7f"
"1axkwrx",
"an84characterslonghumanreadablepartthatcontainsthenumber1andtheexcludedcha"
"ractersbio1569pvx",
"pzry9x0s0muk",
"1pzry9x0s0muk",
"x1b4n0q5v",
@ -32,61 +36,40 @@ struct invalid_address_data {
};
static struct valid_address_data valid_address[] = {
{
"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
22, {
0x00, 0x14, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
}
},
{
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
34, {
0x00, 0x20, 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 0x04,
0xbd, 0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 0x6c, 0x98, 0x56, 0x78,
0xcd, 0x4d, 0x27, 0xa1, 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32,
0x62
}
},
{
"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx",
42, {
0x51, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
{"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4",
22,
{0x00, 0x14, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}},
{"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7",
34,
{0x00, 0x20, 0x18, 0x63, 0x14, 0x3c, 0x14, 0xc5, 0x16, 0x68, 0x04, 0xbd,
0x19, 0x20, 0x33, 0x56, 0xda, 0x13, 0x6c, 0x98, 0x56, 0x78, 0xcd, 0x4d,
0x27, 0xa1, 0xb8, 0xc6, 0x32, 0x96, 0x04, 0x90, 0x32, 0x62}},
{"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grpl"
"x",
42,
{0x51, 0x28, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6,
0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94, 0x1c,
0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6
}
},
{
"BC1SW50QA3JX3S",
4, {
0x60, 0x02, 0x75, 0x1e
}
},
{
"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
18, {
0x52, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54,
0x94, 0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23
}
},
{
"tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
34, {
0x00, 0x20, 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 0x21,
0xb2, 0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 0x36, 0x2b, 0x99, 0xd5,
0xe9, 0x1c, 0x6c, 0xe2, 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64,
0x33
}
}
};
0x45, 0xd1, 0xb3, 0xa3, 0x23, 0xf1, 0x43, 0x3b, 0xd6}},
{"BC1SW50QA3JX3S", 4, {0x60, 0x02, 0x75, 0x1e}},
{"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj",
18,
{0x52, 0x10, 0x75, 0x1e, 0x76, 0xe8, 0x19, 0x91, 0x96, 0xd4, 0x54, 0x94,
0x1c, 0x45, 0xd1, 0xb3, 0xa3, 0x23}},
{"tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy",
34,
{0x00, 0x20, 0x00, 0x00, 0x00, 0xc4, 0xa5, 0xca, 0xd4, 0x62, 0x21, 0xb2,
0xa1, 0x87, 0x90, 0x5e, 0x52, 0x66, 0x36, 0x2b, 0x99, 0xd5, 0xe9, 0x1c,
0x6c, 0xe2, 0x4d, 0x16, 0x5d, 0xab, 0x93, 0xe8, 0x64, 0x33}}};
static const char* invalid_address[] = {
"tc1qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty",
"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5",
"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2",
"bc1rw5uspcuh",
"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90",
"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs"
"90",
"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P",
"tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sL5k7",
"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du",
@ -95,37 +78,19 @@ static const char* invalid_address[] = {
};
static struct invalid_address_data invalid_address_enc[] = {
{"BC", 0, 20},
{"bc", 0, 21},
{"bc", 17, 32},
{"bc", 1, 1},
{"bc", 16, 41},
{"BC", 0, 20}, {"bc", 0, 21}, {"bc", 17, 32}, {"bc", 1, 1}, {"bc", 16, 41},
};
static void segwit_scriptpubkey(uint8_t* scriptpubkey, size_t* scriptpubkeylen, int witver, const uint8_t* witprog, size_t witprog_len) {
static void segwit_scriptpubkey(uint8_t* scriptpubkey, size_t* scriptpubkeylen,
int witver, const uint8_t* witprog,
size_t witprog_len) {
scriptpubkey[0] = witver ? (0x50 + witver) : 0;
scriptpubkey[1] = witprog_len;
memcpy(scriptpubkey + 2, witprog, witprog_len);
*scriptpubkeylen = witprog_len + 2;
}
int my_strncasecmp(const char *s1, const char *s2, size_t n) {
size_t i = 0;
while (i < n) {
char c1 = s1[i];
char c2 = s2[i];
if (c1 >= 'A' && c1 <= 'Z') c1 = (c1 - 'A') + 'a';
if (c2 >= 'A' && c2 <= 'Z') c2 = (c2 - 'A') + 'a';
if (c1 < c2) return -1;
if (c1 > c2) return 1;
if (c1 == 0) return 0;
++i;
}
return 0;
}
START_TEST(test_segwit)
{
START_TEST(test_segwit) {
size_t i;
for (i = 0; i < sizeof(valid_checksum) / sizeof(valid_checksum[0]); ++i) {
uint8_t data[82];
@ -153,31 +118,42 @@ START_TEST(test_segwit)
uint8_t scriptpubkey[42];
size_t scriptpubkey_len;
char rebuild[93];
int ret = segwit_addr_decode(&witver, witprog, &witprog_len, hrp, valid_address[i].address);
int ret = segwit_addr_decode(&witver, witprog, &witprog_len, hrp,
valid_address[i].address);
if (!ret) {
hrp = "tb";
ret = segwit_addr_decode(&witver, witprog, &witprog_len, hrp, valid_address[i].address);
ret = segwit_addr_decode(&witver, witprog, &witprog_len, hrp,
valid_address[i].address);
}
ck_assert_int_eq(ret, 1);
segwit_scriptpubkey(scriptpubkey, &scriptpubkey_len, witver, witprog, witprog_len);
segwit_scriptpubkey(scriptpubkey, &scriptpubkey_len, witver, witprog,
witprog_len);
ck_assert_int_eq(scriptpubkey_len, valid_address[i].scriptPubKeyLen);
ck_assert_int_eq(memcmp(scriptpubkey, valid_address[i].scriptPubKey, scriptpubkey_len), 0);
ck_assert_int_eq(segwit_addr_encode(rebuild, hrp, witver, witprog, witprog_len), 1);
ck_assert_int_eq(
memcmp(scriptpubkey, valid_address[i].scriptPubKey, scriptpubkey_len),
0);
ck_assert_int_eq(
segwit_addr_encode(rebuild, hrp, witver, witprog, witprog_len), 1);
ck_assert_int_eq(my_strncasecmp(valid_address[i].address, rebuild, 93), 0);
}
for (i = 0; i < sizeof(invalid_address) / sizeof(invalid_address[0]); ++i) {
uint8_t witprog[40];
size_t witprog_len;
int witver;
int ret = segwit_addr_decode(&witver, witprog, &witprog_len, "bc", invalid_address[i]);
int ret = segwit_addr_decode(&witver, witprog, &witprog_len, "bc",
invalid_address[i]);
ck_assert_int_eq(ret, 0);
ret = segwit_addr_decode(&witver, witprog, &witprog_len, "tb", invalid_address[i]);
ret = segwit_addr_decode(&witver, witprog, &witprog_len, "tb",
invalid_address[i]);
ck_assert_int_eq(ret, 0);
}
for (i = 0; i < sizeof(invalid_address_enc) / sizeof(invalid_address_enc[0]); ++i) {
for (i = 0; i < sizeof(invalid_address_enc) / sizeof(invalid_address_enc[0]);
++i) {
char rebuild[93];
static const uint8_t program[42] = {0};
int ret = segwit_addr_encode(rebuild, invalid_address_enc[i].hrp, invalid_address_enc[i].version, program, invalid_address_enc[i].program_length);
int ret = segwit_addr_encode(rebuild, invalid_address_enc[i].hrp,
invalid_address_enc[i].version, program,
invalid_address_enc[i].program_length);
ck_assert_int_eq(ret, 0);
}
}

@ -27,34 +27,33 @@
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include <openssl/sha.h>
#include <openssl/opensslv.h>
#include <openssl/sha.h>
#undef SHA256_CTX
#undef SHA512_CTX
#include <stdio.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "ecdsa.h"
#include "rand.h"
#include "hasher.h"
#include "rand.h"
#include "nist256p1.h"
#include "secp256k1.h"
#include "memzero.h"
void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve)
{
uint8_t sig[64], pub_key33[33], pub_key65[65], priv_key[32], msg[256], hash[32];
void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve) {
uint8_t sig[64], pub_key33[33], pub_key65[65], priv_key[32], msg[256],
hash[32];
struct SHA256state_st sha256;
EC_GROUP *ecgroup;
ecgroup = EC_GROUP_new_by_curve_name(nid);
for (unsigned int iter = 0; iter < iterations; iter++) {
// random message len between 1 and 256
int msg_len = (random32() & 0xFF) + 1;
// create random message
@ -73,7 +72,8 @@ void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve)
BN_bn2bin(K, priv_key + bn_off);
// use our ECDSA signer to sign the message with the key
if (ecdsa_sign(curve, HASHER_SHA2, priv_key, msg, msg_len, sig, NULL, NULL) != 0) {
if (ecdsa_sign(curve, HASHER_SHA2, priv_key, msg, msg_len, sig, NULL,
NULL) != 0) {
printf("trezor-crypto signing failed\n");
return;
}
@ -124,8 +124,7 @@ void openssl_check(unsigned int iterations, int nid, const ecdsa_curve *curve)
printf("All OK\n");
}
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("Usage: test_openssl iterations\n");
return 1;

@ -1,186 +1,205 @@
#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "bip32.h"
#include "curves.h"
#include "ecdsa.h"
#include "bip32.h"
#include "secp256k1.h"
#include "nist256p1.h"
#include "ed25519-donna/ed25519.h"
#include "hasher.h"
#include "nist256p1.h"
#include "secp256k1.h"
static uint8_t msg[256];
void prepare_msg(void)
{
void prepare_msg(void) {
for (size_t i = 0; i < sizeof(msg); i++) {
msg[i] = i * 1103515245;
}
}
void bench_sign_secp256k1(int iterations)
{
void bench_sign_secp256k1(int iterations) {
uint8_t sig[64], priv[32], pby;
const ecdsa_curve *curve = &secp256k1;
memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(priv,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
}
}
void bench_sign_nist256p1(int iterations)
{
void bench_sign_nist256p1(int iterations) {
uint8_t sig[64], priv[32], pby;
const ecdsa_curve *curve = &nist256p1;
memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(priv,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
}
}
void bench_sign_ed25519(int iterations)
{
void bench_sign_ed25519(int iterations) {
ed25519_public_key pk;
ed25519_secret_key sk;
ed25519_signature sig;
memcpy(pk, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(pk,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ed25519_publickey(sk, pk);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ed25519_sign(msg, sizeof(msg), sk, pk, sig);
}
}
void bench_verify_secp256k1_33(int iterations)
{
void bench_verify_secp256k1_33(int iterations) {
uint8_t sig[64], pub[33], priv[32], pby;
const ecdsa_curve *curve = &secp256k1;
memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(priv,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key33(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
}
}
void bench_verify_secp256k1_65(int iterations)
{
void bench_verify_secp256k1_65(int iterations) {
uint8_t sig[64], pub[65], priv[32], pby;
const ecdsa_curve *curve = &secp256k1;
memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(priv,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key65(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
}
}
void bench_verify_nist256p1_33(int iterations)
{
void bench_verify_nist256p1_33(int iterations) {
uint8_t sig[64], pub[33], priv[32], pby;
const ecdsa_curve *curve = &nist256p1;
memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(priv,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key33(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
}
}
void bench_verify_nist256p1_65(int iterations)
{
void bench_verify_nist256p1_65(int iterations) {
uint8_t sig[64], pub[65], priv[32], pby;
const ecdsa_curve *curve = &nist256p1;
memcpy(priv, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(priv,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ecdsa_get_public_key65(curve, priv, pub);
ecdsa_sign(curve, HASHER_SHA2, priv, msg, sizeof(msg), sig, &pby, NULL);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ecdsa_verify(curve, HASHER_SHA2, pub, sig, msg, sizeof(msg));
}
}
void bench_verify_ed25519(int iterations)
{
void bench_verify_ed25519(int iterations) {
ed25519_public_key pk;
ed25519_secret_key sk;
ed25519_signature sig;
memcpy(pk, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(pk,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
ed25519_publickey(sk, pk);
ed25519_sign(msg, sizeof(msg), sk, pk, sig);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
ed25519_sign_open(msg, sizeof(msg), pk, sig);
}
}
void bench_multiply_curve25519(int iterations)
{
void bench_multiply_curve25519(int iterations) {
uint8_t result[32];
uint8_t secret[32];
uint8_t basepoint[32];
memcpy(secret, "\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5", 32);
memcpy(basepoint, "\x96\x47\xda\xbe\x1e\xea\xaf\x25\x47\x1e\x68\x0b\x4d\x7c\x6f\xd1\x14\x38\x76\xbb\x77\x59\xd8\x3d\x0f\xf7\xa2\x49\x08\xfd\xda\xbc", 32);
memcpy(secret,
"\xc5\x5e\xce\x85\x8b\x0d\xdd\x52\x63\xf9\x68\x10\xfe\x14\x43\x7c\xd3"
"\xb5\xe1\xfb\xd7\xc6\xa2\xec\x1e\x03\x1f\x05\xe8\x6d\x8b\xd5",
32);
memcpy(basepoint,
"\x96\x47\xda\xbe\x1e\xea\xaf\x25\x47\x1e\x68\x0b\x4d\x7c\x6f\xd1\x14"
"\x38\x76\xbb\x77\x59\xd8\x3d\x0f\xf7\xa2\x49\x08\xfd\xda\xbc",
32);
for (int i = 0 ; i < iterations; i++) {
for (int i = 0; i < iterations; i++) {
curve25519_scalarmult(result, secret, basepoint);
}
}
static HDNode root;
void prepare_node(void)
{
void prepare_node(void) {
hdnode_from_seed((uint8_t *)"NothingToSeeHere", 16, SECP256K1_NAME, &root);
hdnode_fill_public_key(&root);
}
void bench_ckd_normal(int iterations)
{
void bench_ckd_normal(int iterations) {
char addr[MAX_ADDR_SIZE];
HDNode node;
for (int i = 0; i < iterations; i++) {
memcpy(&node, &root, sizeof(HDNode));
hdnode_public_ckd(&node, i);
hdnode_fill_public_key(&node);
ecdsa_get_address(node.public_key, HASHER_SHA2, HASHER_SHA2D, 0, addr, sizeof(addr));
ecdsa_get_address(node.public_key, HASHER_SHA2, HASHER_SHA2D, 0, addr,
sizeof(addr));
}
}
void bench_ckd_optimized(int iterations)
{
void bench_ckd_optimized(int iterations) {
char addr[MAX_ADDR_SIZE];
curve_point pub;
ecdsa_read_pubkey(&secp256k1, root.public_key, &pub);
for (int i = 0; i < iterations; i++) {
hdnode_public_ckd_address_optimized(&pub, root.chain_code, i, 0, HASHER_SHA2, HASHER_SHA2D, addr, sizeof(addr), false);
hdnode_public_ckd_address_optimized(&pub, root.chain_code, i, 0,
HASHER_SHA2, HASHER_SHA2D, addr,
sizeof(addr), false);
}
}
void bench(void (*func)(int), const char *name, int iterations)
{
void bench(void (*func)(int), const char *name, int iterations) {
clock_t t = clock();
func(iterations);
float speed = iterations / ((float)(clock() - t) / CLOCKS_PER_SEC);
@ -190,7 +209,6 @@ void bench(void (*func)(int), const char *name, int iterations)
#define BENCH(FUNC, ITER) bench(FUNC, #FUNC, ITER)
int main(void) {
prepare_msg();
BENCH(bench_sign_secp256k1, 500);

@ -1,10 +1,10 @@
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "bip39.h"
#include <time.h>
#include "bip32.h"
#include "ecdsa.h"
#include "bip39.h"
#include "curves.h"
#include "ecdsa.h"
#include "secp256k1.h"
char iter[256];
@ -26,8 +26,7 @@ clock_t start;
// address: "1N3uJ5AU3FTYQ1ZQgTMtYmgSvMBmQiGVBS"
// passphrase: "testing"
int main(int argc, char **argv)
{
int main(int argc, char **argv) {
if (argc != 2 && argc != 3) {
fprintf(stderr, "Usage: bip39bruteforce address [mnemonic]\n");
return 1;
@ -71,14 +70,16 @@ int main(int argc, char **argv)
hdnode_private_ckd(&node, 0);
hdnode_private_ckd(&node, 0);
hdnode_fill_public_key(&node);
ecdsa_get_pubkeyhash(node.public_key, secp256k1_info.hasher_pubkey, pubkeyhash);
ecdsa_get_pubkeyhash(node.public_key, secp256k1_info.hasher_pubkey,
pubkeyhash);
if (memcmp(addr + 1, pubkeyhash, 20) == 0) {
found = 1;
break;
}
}
float dur = (float)(clock() - start) / CLOCKS_PER_SEC;
printf("Tried %d %ss in %f seconds = %f tries/second\n", count, item, dur, (float)count/dur);
printf("Tried %d %ss in %f seconds = %f tries/second\n", count, item, dur,
(float)count / dur);
if (found) {
printf("Correct %s found! :-)\n\"%s\"\n", item, iter);
return 0;

@ -1,8 +1,8 @@
#include <stdio.h>
#include <assert.h>
#include <stdio.h>
#include "bignum.h"
#include "ecdsa.h"
#include "bip32.h"
#include "ecdsa.h"
#include "rand.h"
/*
@ -11,7 +11,7 @@
* where G is the generator of the specified elliptic curve.
*/
int main(int argc, char **argv) {
int i,j,k;
int i, j, k;
if (argc != 2) {
printf("Usage: %s CURVE_NAME\n", argv[0]);
return 1;
@ -39,12 +39,12 @@ int main(int argc, char **argv) {
curve_point checkresult;
bignum256 a;
bn_zero(&a);
a.val[(4*i) / 30] = ((uint32_t) 2*j+1) << ((4*i) % 30);
a.val[(4 * i) / 30] = ((uint32_t)2 * j + 1) << ((4 * i) % 30);
bn_normalize(&a);
point_multiply(curve, &a, &curve->G, &checkresult);
assert(point_is_equal(&checkresult, &ng));
#endif
printf("\t\t/* %2d*16^%d*G: */\n\t\t{{{", 2*j + 1, i);
printf("\t\t/* %2d*16^%d*G: */\n\t\t{{{", 2 * j + 1, i);
// print x coordinate
for (k = 0; k < 9; k++) {
printf((k < 8 ? "0x%08x, " : "0x%04x"), ng.x.val[k]);

@ -1,7 +1,7 @@
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>
#include "bip32.h"
#include "curves.h"
#include "ecdsa.h"
@ -9,10 +9,12 @@
#define VERSION_PUBLIC 0x0488b21e
#define VERSION_PRIVATE 0x0488ade4
void process_job(uint32_t jobid, const char *xpub, uint32_t change, uint32_t from, uint32_t to)
{
void process_job(uint32_t jobid, const char *xpub, uint32_t change,
uint32_t from, uint32_t to) {
HDNode node, child;
if (change > 1 || to <= from || hdnode_deserialize(xpub, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME, &node, NULL) != 0) {
if (change > 1 || to <= from ||
hdnode_deserialize(xpub, VERSION_PUBLIC, VERSION_PRIVATE, SECP256K1_NAME,
&node, NULL) != 0) {
printf("%d error\n", jobid);
return;
}
@ -22,13 +24,13 @@ void process_job(uint32_t jobid, const char *xpub, uint32_t change, uint32_t fro
for (i = from; i < to; i++) {
memcpy(&child, &node, sizeof(HDNode));
hdnode_public_ckd(&child, i);
ecdsa_get_address(child.public_key, 0, HASHER_SHA2, HASHER_SHA2D, address, sizeof(address));
ecdsa_get_address(child.public_key, 0, HASHER_SHA2, HASHER_SHA2D, address,
sizeof(address));
printf("%d %d %s\n", jobid, i, address);
}
}
int main(void)
{
int main(void) {
char line[1024], xpub[1024];
uint32_t jobid, change, from, to;
int r;

Loading…
Cancel
Save