mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-16 17:42:02 +00:00
format: start using clang-format with style=Google
This commit is contained in:
parent
8434b2468c
commit
0c622d62e1
2
.clang-format
Normal file
2
.clang-format
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
BasedOnStyle: Google
|
26
address.c
26
address.c
@ -24,24 +24,21 @@
|
||||
#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]);
|
||||
}
|
||||
@ -49,16 +46,19 @@ bool address_check_prefix(const uint8_t *addr, uint32_t address_type)
|
||||
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,7 +71,8 @@ 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);
|
||||
@ -81,7 +82,8 @@ void ethereum_address_checksum(const uint8_t *addr, char *address, bool rskip60,
|
||||
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
|
||||
|
21
base32.c
21
base32.c
@ -27,13 +27,17 @@
|
||||
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;
|
||||
@ -55,7 +59,8 @@ 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;
|
||||
@ -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;
|
||||
}
|
||||
|
9
base32.h
9
base32.h
@ -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);
|
||||
|
121
base58.c
121
base58.c
@ -21,28 +21,27 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include "base58.h"
|
||||
#include "sha2.h"
|
||||
#include "ripemd160.h"
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.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) {
|
||||
@ -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;
|
||||
}
|
||||
|
14
base58.h
14
base58.h
@ -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
|
||||
|
186
bignum.c
186
bignum.c
@ -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++) {
|
||||
@ -108,8 +99,7 @@ void bn_read_be(const uint8_t *in_number, bignum256 *out_number)
|
||||
|
||||
// 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++) {
|
||||
@ -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++) {
|
||||
@ -143,8 +132,7 @@ void bn_read_le(const uint8_t *in_number, bignum256 *out_number)
|
||||
|
||||
// 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++) {
|
||||
@ -156,8 +144,7 @@ void bn_write_le(const bignum256 *in_number, uint8_t *out_number)
|
||||
}
|
||||
}
|
||||
|
||||
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 fmask = ~tmask;
|
||||
|
||||
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,8 +327,7 @@ 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
|
||||
@ -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,8 +381,7 @@ void bn_multiply_long(const bignum256 *k, const bignum256 *x, uint32_t res[18])
|
||||
temp >>= 30;
|
||||
}
|
||||
// compute upper half
|
||||
for (; i < 17; i++)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
@ -561,8 +529,7 @@ void bn_sqrt(bignum256 *x, const bignum256 *prime)
|
||||
#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];
|
||||
@ -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
|
||||
@ -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) {
|
||||
@ -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];
|
||||
@ -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]);
|
||||
|
33
bignum.h
33
bignum.h
@ -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
|
||||
|
214
bip32.c
214
bip32.c
@ -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 "curves.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"
|
||||
#include "base58.h"
|
||||
#include "curves.h"
|
||||
#include "secp256k1.h"
|
||||
#include "nist256p1.h"
|
||||
#include "ed25519-donna/ed25519.h"
|
||||
#include "ed25519-donna/ed25519-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;
|
||||
@ -116,8 +117,9 @@ int hdnode_from_xpub(uint32_t depth, uint32_t child_num, const uint8_t *chain_co
|
||||
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);
|
||||
|
70
bip32.h
70
bip32.h
@ -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);
|
||||
|
||||
|
47
bip39.c
47
bip39.c
@ -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; }
|
||||
|
5
bip39.h
5
bip39.h
@ -37,7 +37,10 @@ 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);
|
||||
|
||||
|
2391
bip39_english.h
2391
bip39_english.h
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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
static inline uint64_t rotr64(const uint64_t w, const unsigned c) {
|
||||
return (w >> c) | (w << (64 - c));
|
||||
}
|
||||
|
||||
|
36
cash_addr.c
36
cash_addr.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) {
|
||||
@ -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,7 +174,8 @@ 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];
|
||||
size_t data_len;
|
||||
|
41
cash_addr.h
41
cash_addr.h
@ -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
|
||||
|
228
ecdsa.c
228
ecdsa.c
@ -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 "bignum.h"
|
||||
#include "rand.h"
|
||||
#include "hmac.h"
|
||||
#include "ecdsa.h"
|
||||
#include "base58.h"
|
||||
#include "secp256k1.h"
|
||||
#include "rfc6979.h"
|
||||
#include "bignum.h"
|
||||
#include "ecdsa.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,8 +164,7 @@ 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);
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -423,8 +416,8 @@ 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
|
||||
@ -548,8 +541,8 @@ 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)
|
||||
{
|
||||
void scalar_multiply(const ecdsa_curve *curve, const bignum256 *k,
|
||||
curve_point *res) {
|
||||
assert(bn_is_less(k, &curve->order));
|
||||
|
||||
int i, j;
|
||||
@ -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,7 +654,8 @@ 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) {
|
||||
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];
|
||||
|
||||
@ -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 = 0x30;
|
||||
p++; // sequence
|
||||
*p = 0x00;
|
||||
len = p;
|
||||
p++; // len(sequence)
|
||||
|
||||
*p = 0x02; p++; // integer
|
||||
*p = 0x00; len1 = p; p++; // len(integer)
|
||||
*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;
|
||||
|
75
ecdsa.h
75
ecdsa.h
@ -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
|
||||
|
9
hasher.c
9
hasher.c
@ -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);
|
||||
|
12
hasher.h
12
hasher.h
@ -26,11 +26,11 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "blake256.h"
|
||||
#include "blake2b.h"
|
||||
#include "groestl.h"
|
||||
#include "sha2.h"
|
||||
#include "sha3.h"
|
||||
#include "blake256.h"
|
||||
#include "groestl.h"
|
||||
#include "blake2b.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
|
||||
|
40
hmac.c
40
hmac.c
@ -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,16 +59,16 @@ 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)
|
||||
{
|
||||
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));
|
||||
@ -102,8 +101,8 @@ void hmac_sha256_prepare(const uint8_t *key, const uint32_t keylen, uint32_t *op
|
||||
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,16 +133,16 @@ 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)
|
||||
{
|
||||
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));
|
||||
|
24
hmac.h
24
hmac.h
@ -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
|
||||
|
12
memzero.c
12
memzero.c
@ -18,7 +18,8 @@
|
||||
#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
|
||||
|
||||
@ -42,10 +43,10 @@
|
||||
#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)
|
||||
@ -55,8 +56,7 @@ void memzero(void *const pnt, const size_t len)
|
||||
#elif defined(HAVE_EXPLICIT_MEMSET)
|
||||
explicit_memset(pnt, 0, len);
|
||||
#else
|
||||
volatile unsigned char *volatile pnt_ =
|
||||
(volatile unsigned char *volatile) pnt;
|
||||
volatile unsigned char *volatile pnt_ = (volatile unsigned char *volatile)pnt;
|
||||
size_t i = (size_t)0U;
|
||||
|
||||
while (i < len) {
|
||||
|
@ -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
|
||||
|
@ -4,22 +4,22 @@
|
||||
|
||||
#include "range_proof.h"
|
||||
|
||||
|
||||
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};
|
||||
@ -50,7 +50,8 @@ void xmr_gen_range_sig_ex(xmr_range_sig_t * sig, ge25519 * C, bignum256modm mask
|
||||
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]);
|
||||
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
55
monero/xmr.c
55
monero/xmr.c
@ -4,21 +4,20 @@
|
||||
|
||||
#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}
|
||||
};
|
||||
{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 ge25519_set_xmr_h(ge25519 *r) { ge25519_copy(r, &xmr_h); }
|
||||
|
||||
void xmr_random_scalar(bignum256modm m) {
|
||||
unsigned char buff[32] = {0};
|
||||
@ -30,9 +29,7 @@ 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) {
|
||||
hasher_Update(hasher, data, length);
|
||||
@ -61,25 +58,29 @@ 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){
|
||||
void xmr_derive_public_key(ge25519 *r, const ge25519 *deriv, uint32_t idx,
|
||||
const ge25519 *base) {
|
||||
bignum256modm s = {0};
|
||||
ge25519 p2;
|
||||
|
||||
@ -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,7 +129,8 @@ 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));
|
||||
}
|
||||
|
27
monero/xmr.h
27
monero/xmr.h
@ -39,27 +39,36 @@ 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);
|
||||
|
301
nem.c
301
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_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,13 +241,10 @@ bool nem_transaction_create_transfer(nem_transaction_ctx *ctx,
|
||||
length = 0;
|
||||
}
|
||||
|
||||
bool ret = nem_transaction_write_common(ctx,
|
||||
NEM_TRANSACTION_TYPE_TRANSFER,
|
||||
bool ret =
|
||||
nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_TRANSFER,
|
||||
(uint32_t)network << 24 | (mosaics ? 2 : 1),
|
||||
timestamp,
|
||||
signer,
|
||||
fee,
|
||||
deadline);
|
||||
timestamp, signer, fee, deadline);
|
||||
if (!ret) return false;
|
||||
|
||||
SERIALIZE_TAGGED((const uint8_t *)recipient, NEM_ADDRESS_SIZE);
|
||||
@ -250,22 +259,19 @@ 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);
|
||||
@ -276,25 +282,18 @@ bool nem_transaction_write_mosaic(nem_transaction_ctx *ctx,
|
||||
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,
|
||||
bool ret = nem_transaction_write_common(ctx, NEM_TRANSACTION_TYPE_MULTISIG,
|
||||
(uint32_t)network << 24 | 1,
|
||||
timestamp,
|
||||
signer,
|
||||
fee,
|
||||
deadline);
|
||||
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];
|
||||
@ -336,28 +327,18 @@ bool nem_transaction_create_multisig_signature(nem_transaction_ctx *ctx,
|
||||
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) {
|
||||
@ -375,43 +356,27 @@ bool nem_transaction_create_provision_namespace(nem_transaction_ctx *ctx,
|
||||
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;
|
||||
@ -427,15 +392,18 @@ bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
|
||||
|
||||
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_U32(levy_identifier_length);
|
||||
@ -453,36 +421,25 @@ bool nem_transaction_create_mosaic_creation(nem_transaction_ctx *ctx,
|
||||
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);
|
||||
@ -493,26 +450,18 @@ bool nem_transaction_create_mosaic_supply_change(nem_transaction_ctx *ctx,
|
||||
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);
|
||||
|
||||
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);
|
||||
|
149
nem.h
149
nem.h
@ -52,11 +52,15 @@
|
||||
|
||||
#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) \
|
||||
(_NEM_PADDING_SIZE(buffer, size) > (size) ? (size) \
|
||||
: _NEM_PADDING_SIZE(buffer, size))
|
||||
|
||||
#define NEM_DECRYPTED_SIZE(buffer, size) ((size)-NEM_PADDING_SIZE(buffer, size))
|
||||
|
||||
@ -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_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_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_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_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
|
||||
|
37
nist256p1.c
37
nist256p1.c
@ -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;
|
||||
|
38
pbkdf2.c
38
pbkdf2.c
@ -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);
|
||||
@ -54,8 +55,8 @@ 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);
|
||||
@ -66,8 +67,7 @@ void pbkdf2_hmac_sha256_Update(PBKDF2_HMAC_SHA256_CTX *pctx, uint32_t iterations
|
||||
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++) {
|
||||
REVERSE32(pctx->f[k], pctx->f[k]);
|
||||
@ -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);
|
||||
@ -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,8 +143,7 @@ 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++) {
|
||||
REVERSE64(pctx->f[k], pctx->f[k]);
|
||||
@ -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) {
|
||||
|
22
pbkdf2.h
22
pbkdf2.h
@ -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
|
||||
|
31
rand.c
31
rand.c
@ -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];
|
||||
|
2
rc4.h
2
rc4.h
@ -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];
|
||||
|
11
rfc6979.c
11
rfc6979.c
@ -22,12 +22,13 @@
|
||||
* 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) {
|
||||
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];
|
||||
|
||||
@ -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
|
||||
|
12
script.c
12
script.c
@ -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);
|
||||
|
3
script.h
3
script.h
@ -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
|
||||
|
35
secp256k1.c
35
secp256k1.c
@ -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 ];
|
||||
}
|
||||
|
7105
tests/test_check.c
7105
tests/test_check.c
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
|
||||
static const char
|
||||
*vectors[] =
|
||||
{
|
||||
"6065a956b1b34145c4416fdc3ba3276801850e91a77a31a7be782463288aea5"
|
||||
"3", // private key
|
||||
"60ba6e25b1a02157fb69c5d1d7b96c4619736e545447069a6a6f0ba90844bc8"
|
||||
"e", // private key extension
|
||||
"64b20fa082b3143d6b5eed42c6ef63f99599d0888afe060620abc1b319935fe"
|
||||
"1", // public key
|
||||
"45b1a75fe3119e13c6f60ab9ba674b42f946fdc558e07c83dfa0751c2eba69c7"
|
||||
"9331bd8a4a975662b23628a438a0eba76367e44c12ca91b39ec59063f860f10"
|
||||
"d", // signature
|
||||
|
||||
"e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830c", // private key
|
||||
"794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a4", // private key extension
|
||||
"95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931df", // public key
|
||||
"f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b19ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560f", // signature
|
||||
"e7d27516538403a53a8b041656a3f570909df641a0ab811fe7d87c9ba02a830"
|
||||
"c", // private key
|
||||
"794a2c54ad8b525b781773c87d38cbf4197636bc427a9d551368286fe4c294a"
|
||||
"4", // private key extension
|
||||
"95bb82ffd5707716bc65170ab4e8dafeed90fbe0ce9258713b7751e962d931d"
|
||||
"f", // public key
|
||||
"f2c9171782e7df7665126ac545ae53b05964b0160536efdb545e2460dbbec2b1"
|
||||
"9ec6b338b8f1bf4dfee94360ed024b115e37b1d7e6f3f9ae4beb79539428560"
|
||||
"f", // signature
|
||||
|
||||
"9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0c", // private key
|
||||
"b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedebb", // private key extension
|
||||
"79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19f", // public key
|
||||
"2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800f", // signature
|
||||
"9b5a3d9a4c60bcd49bb64b72c082b164314d0f61d842f2575fd1d4fb30a28a0"
|
||||
"c", // private key
|
||||
"b093e376f41eb7bf80abcd0073a52455d25b5d21815bc758e5f6f81536aedeb"
|
||||
"b", // private key extension
|
||||
"79fc8154554b97e4c56ef2f9dbb4c1421ff19509688931a1e964bda5dec0f19"
|
||||
"f", // public key
|
||||
"2ba1439ae648a7e8da7c9ab1ee6da94fd4ebe37abd0978306e8fba2afa8f111a"
|
||||
"88a993dbf008bedae9167f4f68409e4c9ddaf02cba12418447b1848907ad800"
|
||||
"f", // signature
|
||||
|
||||
"52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40c", // private key
|
||||
"6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a25803", // private key extension
|
||||
"dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d6", // public key
|
||||
"0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a62a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd781602", // signature
|
||||
"52e0c98aa600cfdcd1ff28fcda5227ed87063f4a98547a78b771052cf102b40"
|
||||
"c", // private key
|
||||
"6c18d9f8075b1a6a1833540607479bd58b7beb8a83d2bb01ca7ae02452a2580"
|
||||
"3", // private key extension
|
||||
"dc907c7c06e6314eedd9e18c9f6c6f9cc4e205fb1c70da608234c319f1f7b0d"
|
||||
"6", // public key
|
||||
"0cd34f84e0d2fcb1800bdb0e869b9041349955ced66aedbe6bda187ebe8d36a6"
|
||||
"2a05b39647e92fcc42aa7a7368174240afba08b8c81f981a22f942d6bd78160"
|
||||
"2", // signature
|
||||
|
||||
"11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec04", // private key
|
||||
"c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a5473402352", // private key extension
|
||||
"839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db78", // public key
|
||||
"e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa4905", // signature
|
||||
"11fd6462a3a92b35c22703f6f1c124ddcf36b7c2b09cc2784f320e1cfa12ec0"
|
||||
"4", // private key
|
||||
"c2785803c61c46aeca192a1bb1b7b20a8c4cc7fa01db57fc5d1d8a547340235"
|
||||
"2", // private key extension
|
||||
"839775a41876e328986aa26168958bba1176e67819b357eea84afceab8b1db7"
|
||||
"8", // public key
|
||||
"e41f73db2f8d2896a687802b2be76b7cabb73dfbb4891494883a0cbd9bbb9e5f"
|
||||
"9d3e14d2d0b06c6674333508496db660936737c0efd9511514147dac79fa490"
|
||||
"5", // signature
|
||||
|
||||
"5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e505", // private key
|
||||
"ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098cd", // private key extension
|
||||
"75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb76", // public key
|
||||
"631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fbc10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda598906", // signature
|
||||
"5b1e5cad02274ba461f4708d8598d3497faf8fe3e894a379573aa6ac3a03e50"
|
||||
"5", // private key
|
||||
"ba179d2e3c67aabb486c48d16002b51ad32eab434c738a1550962313b07098c"
|
||||
"d", // private key extension
|
||||
"75eb8d197ec8627c85af88e66aa1e49065dd8ac98ed8991db52ece01635dfb7"
|
||||
"6", // public key
|
||||
"631015357cee3051116b4c2ff4d1c5beb13b6e5023635aa1eeb0563cadf0d4fb"
|
||||
"c10bd5e31b4a4220c67875558c41b5cc0328104ae39cc7ff20ff0c2bda59890"
|
||||
"6", // signature
|
||||
|
||||
"624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50d", // private key
|
||||
"097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b02", // private key extension
|
||||
"0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b00", // public key
|
||||
"1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f901", // signature
|
||||
"624b47150f58dfa44284fbc63c9f99b9b79f808c4955a461f0e2be44eb0be50"
|
||||
"d", // private key
|
||||
"097aa006d694b165ef37cf23562e5967c96e49255d2f20faae478dee83aa5b0"
|
||||
"2", // private key extension
|
||||
"0588589cd9b51dfc028cf225674069cbe52e0e70deb02dc45b79b26ee3548b0"
|
||||
"0", // public key
|
||||
"1de1d275428ba9491a433cd473cd076c027f61e7a8b5391df9dea5cb4bc88d8a"
|
||||
"57b095906a30b13e68259851a8dd3f57b6f0ffa37a5d3ffc171240f2d404f90"
|
||||
"1", // signature
|
||||
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
const char **test_data;
|
||||
@ -60,7 +97,8 @@ 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);
|
||||
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,7 +34,8 @@ START_TEST(test_xmr_base58)
|
||||
|
||||
memcpy(rawn, fromhex(raw), len);
|
||||
|
||||
r = xmr_base58_addr_encode_check(tests[i].tag, rawn, len, strn, sizeof(strn));
|
||||
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);
|
||||
|
||||
@ -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,9 +637,7 @@ START_TEST(test_xmr_fast_hash)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(test_xmr_hasher)
|
||||
{
|
||||
START_TEST(test_xmr_hasher) {
|
||||
Hasher hasher;
|
||||
uint8_t hash[32];
|
||||
|
||||
@ -703,14 +649,16 @@ START_TEST(test_xmr_hasher)
|
||||
"f84a97f1f0a956e738abd85c2e0a5026f8874e3ec09c8f012159dfeeaab2b156"},
|
||||
{{"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);
|
||||
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;
|
||||
@ -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,
|
||||
};
|
||||
|
@ -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,58 +1,63 @@
|
||||
#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++) {
|
||||
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++) {
|
||||
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++) {
|
||||
@ -60,13 +65,15 @@ void bench_sign_ed25519(int iterations)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -75,13 +82,15 @@ void bench_verify_secp256k1_33(int iterations)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -90,13 +99,15 @@ void bench_verify_secp256k1_65(int iterations)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -105,13 +116,15 @@ void bench_verify_nist256p1_33(int iterations)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -120,13 +133,15 @@ void bench_verify_nist256p1_65(int iterations)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@ -135,14 +150,19 @@ void bench_verify_ed25519(int iterations)
|
||||
}
|
||||
}
|
||||
|
||||
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++) {
|
||||
curve25519_scalarmult(result, secret, basepoint);
|
||||
@ -151,36 +171,35 @@ void bench_multiply_curve25519(int iterations)
|
||||
|
||||
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"
|
||||
|
||||
/*
|
||||
|
@ -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…
Reference in New Issue
Block a user