Skip to content
This repository has been archived by the owner on Jun 11, 2022. It is now read-only.

Commit

Permalink
import entropy from english mnemonics
Browse files Browse the repository at this point in the history
  • Loading branch information
ecioppettini committed Mar 12, 2019
1 parent 5bbbffd commit 3705f4c
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 0 deletions.
30 changes: 30 additions & 0 deletions cardano-c/cardano.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,36 @@ typedef int cardano_result;
/* BIP39 */
/*********/

/* bip39 error definitions */
enum _bip39_config_error
{
SUCCESS = 0,
INVALID_MNEMONIC = 1,
INVALID_CHECKSUM = 2
};

/* type for the API user */
typedef enum _config_error cardano_bip39_error_t;

/* Error descriptions */
struct _errordesc {
int code;
char *message;
} errordesc[] = {
{ SUCCESS, "No error" },
{ INVALID_MNEMONIC, "Invalid mnemonic word" },
{ INVALID_CHECKSUM, "Invalid checksum" },
};

typedef uint8_t* cardano_entropy;

int cardano_entropy_from_mnemonics(
const char *mnemonics,
cardano_entropy *entropy,
uint32_t *entropy_size
);
void cardano_delete_entropy_array(uint8_t *entropy, size_t bytes);

cardano_result cardano_bip39_encode(const char * const entropy_raw, unsigned long entropy_size, unsigned short *mnemonic_index, unsigned long mnemonic_size);

/*********/
Expand Down
68 changes: 68 additions & 0 deletions cardano-c/src/bip39.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ use std::slice;
use cardano::bip::bip39;
use types::CardanoResult;

use std::{
ptr,
os::raw::{c_char, c_uchar, c_int, c_uint},
};

use std::ffi::CStr;

/// encode a entropy into its equivalent words represented by their index (0 to 2047) in the BIP39 dictionary
#[no_mangle]
pub extern "C" fn cardano_bip39_encode(
Expand All @@ -20,3 +27,64 @@ pub extern "C" fn cardano_bip39_encode(
out_slice.copy_from_slice(entropy.to_mnemonics().as_ref());
CardanoResult::success()
}

///
/// Error status:
/// 0: Success
/// 1: The words were not in the english dictionary
/// 2: The checksum was invalid
///
#[no_mangle]
pub extern "C" fn cardano_entropy_from_mnemonics(
mnemonics: *const c_char,
entropy_ptr: *mut *const c_uchar,
entropy_size: *mut c_uint
) -> c_int {
let rust_string = unsafe { CStr::from_ptr(mnemonics) }.to_string_lossy();

let dictionary = bip39::dictionary::ENGLISH;

let mnemonics = match bip39::Mnemonics::from_string(&dictionary, &rust_string)
{
Ok(m) => m,
Err(_) => return 1,
};

let entropy = match bip39::Entropy::from_mnemonics(&mnemonics) {
Ok(e) => e,
Err(_) => return 2,
};

let mut entropy_vec = match entropy {
bip39::Entropy::Entropy9(arr) => arr.to_vec(),
bip39::Entropy::Entropy12(arr) => arr.to_vec(),
bip39::Entropy::Entropy15(arr) => arr.to_vec(),
bip39::Entropy::Entropy18(arr) => arr.to_vec(),
bip39::Entropy::Entropy21(arr) => arr.to_vec(),
bip39::Entropy::Entropy24(arr) => arr.to_vec(),
};

//Make sure the capacity is the same as the length to make deallocation simpler
entropy_vec.shrink_to_fit();

let pointer = entropy_vec.as_mut_ptr();
let length = entropy_vec.len() as u32;

//To avoid deallocation
std::mem::forget(entropy_vec);

//Write the array length
unsafe { ptr::write(entropy_size, length) }

//Copy the pointer to the out parameter
unsafe { ptr::write(entropy_ptr, pointer) };

0
}

//Deallocate the rust-allocated memory for a Entropy array
#[no_mangle]
pub extern "C" fn cardano_delete_entropy_array(ptr: *mut c_uchar, size: u32) {
let len = size as usize;
unsafe { drop(Vec::from_raw_parts(ptr, len, len)) };
}
43 changes: 43 additions & 0 deletions cardano-c/test/test_bip39_entropy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "../cardano.h"
#include "unity/unity.h"

void test_generate_entropy_from_mnemonics(void) {
static const char *mnemonics = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

cardano_entropy entropy;
uint32_t bytes;
int error = cardano_entropy_from_mnemonics(mnemonics, &entropy, &bytes);

uint8_t expected[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, entropy, 16);

cardano_delete_entropy_array(entropy, bytes);
}

void test_generate_entropy_from_mnemonics_error_code_invalid_word(void) {
static const char *mnemonics = "termo abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

cardano_entropy entropy;
uint32_t bytes;
int error = cardano_entropy_from_mnemonics(mnemonics, &entropy, &bytes);

TEST_ASSERT_EQUAL_HEX32(INVALID_MNEMONIC, error);
}

void test_generate_entropy_from_mnemonics_invalid_checksum(void) {
static const char *mnemonics = "about abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

cardano_entropy entropy;
uint32_t bytes;
int error = cardano_entropy_from_mnemonics(mnemonics, &entropy, &bytes);

TEST_ASSERT_EQUAL_HEX32(INVALID_CHECKSUM, error);
}

int main(void) {
UNITY_BEGIN();
RUN_TEST(test_generate_entropy_from_mnemonics);
RUN_TEST(test_generate_entropy_from_mnemonics_error_code_invalid_word);
RUN_TEST(test_generate_entropy_from_mnemonics_invalid_checksum);
return UNITY_END();
}

0 comments on commit 3705f4c

Please sign in to comment.