Skip to content

Commit

Permalink
move chacha to rust implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
chcmedeiros committed Oct 10, 2024
1 parent 4f8da8b commit e665fc5
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 194 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ file(GLOB_RECURSE LIB_SRC
${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/parser_impl_common.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper.c
${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper/chacha.c

# ###
${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref/blake2b-ref.c
Expand All @@ -150,7 +149,6 @@ target_include_directories(app_lib PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/deps/ledger-zxlib/include
${CMAKE_CURRENT_SOURCE_DIR}/app/src
${CMAKE_CURRENT_SOURCE_DIR}/app/src/lib
${CMAKE_CURRENT_SOURCE_DIR}/app/src/crypto_helper
${CMAKE_CURRENT_SOURCE_DIR}/app/src/common
${CMAKE_CURRENT_SOURCE_DIR}/app/rust/include
${CMAKE_CURRENT_SOURCE_DIR}/deps/blake2/ref
Expand Down
141 changes: 141 additions & 0 deletions app/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ crate-type = ["staticlib"]
[dependencies]
jubjub = { version = "0.10.0", default-features = false }
blake2b_simd = { version = "1.0.0", default-features = false }
chacha20poly1305 = { version = "0.10.1", default-features = false }

[target.thumbv6m-none-eabi.dev-dependencies]
panic-halt = "0.2.0"
Expand Down
4 changes: 4 additions & 0 deletions app/rust/include/rslib.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ parser_error_t compute_sbar(const uint8_t s[KEY_LENGTH], const uint8_t r[KEY_LEN
uint8_t sbar[32]);
parser_error_t shared_secret(uint8_t secret_key[32], uint8_t other_public_key[32], const uint8_t reference_public_key[32],
uint8_t output[32]);
parser_error_t decrypt_note_encryption_keys(const uint8_t key[KEY_LENGTH], const uint8_t note_encryption_keys[80],
uint8_t output[ENCRYPTED_SHARED_KEY_SIZE]);
parser_error_t decrypt_note(const uint8_t key[KEY_LENGTH], const uint8_t note[ENCRYPTED_NOTE_SIZE + MAC_SIZE],
uint8_t output[ENCRYPTED_NOTE_SIZE]);
#ifdef __cplusplus
}
#endif
2 changes: 1 addition & 1 deletion app/rust/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub const MEMO_SIZE: usize = 32;
pub const AMOUNT_VALUE_SIZE: usize = 8;
pub const ASSET_ID_LENGTH: usize = 32;
pub const PUBLIC_ADDRESS_SIZE: usize = 32;

pub const EPHEMEREAL_PUBLIC_KEY_SIZE: usize = 32;
pub const ENCRYPTED_NOTE_SIZE: usize =
SCALAR_SIZE + MEMO_SIZE + AMOUNT_VALUE_SIZE + ASSET_ID_LENGTH + PUBLIC_ADDRESS_SIZE;

Expand Down
52 changes: 50 additions & 2 deletions app/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@

use core::panic::PanicInfo;

use chacha20poly1305::{aead::generic_array::GenericArray, ChaCha20Poly1305, Key, KeyInit, Nonce};
use constants::{
DIFFIE_HELLMAN_PERSONALIZATION, ENCRYPTED_NOTE_SIZE, ENCRYPTED_SHARED_KEY_SIZE, MAC_SIZE,
NOTE_ENCRYPTION_KEY_SIZE, SHARED_KEY_PERSONALIZATION, SPENDING_KEY_GENERATOR,
DIFFIE_HELLMAN_PERSONALIZATION, ENCRYPTED_NOTE_SIZE, ENCRYPTED_SHARED_KEY_SIZE,
EPHEMEREAL_PUBLIC_KEY_SIZE, MAC_SIZE, NOTE_ENCRYPTION_KEY_SIZE, SHARED_KEY_PERSONALIZATION,
SPENDING_KEY_GENERATOR,
};
mod constants;

Expand Down Expand Up @@ -150,6 +152,52 @@ pub extern "C" fn shared_secret(
ParserError::ParserOk
}

fn decrypt<const SIZE: usize>(
key: &[u8; 32],
ciphertext: &[u8],
plaintext: &mut [u8; SIZE],
) -> ParserError {
use chacha20poly1305::AeadInPlace;

// Check if the ciphertext length is sufficient
if ciphertext.len() < SIZE {
return ParserError::ParserUnexpectedError; // Return an error if insufficient data
}

let decryptor = ChaCha20Poly1305::new(Key::from_slice(key));

plaintext.copy_from_slice(&ciphertext[..SIZE]);

// Attempt decryption
match decryptor.decrypt_in_place_detached(
&Nonce::default(),
&[],
plaintext,
ciphertext[SIZE..].into(),
) {
Ok(_) => ParserError::ParserOk,
Err(_) => ParserError::ParserUnexpectedError, // Handle decryption failure
}
}

#[no_mangle]
pub extern "C" fn decrypt_note_encryption_keys(
key: &[u8; 32],
ciphertext: &[u8; NOTE_ENCRYPTION_KEY_SIZE],
output: &mut [u8; ENCRYPTED_SHARED_KEY_SIZE],
) -> ParserError {
decrypt::<ENCRYPTED_SHARED_KEY_SIZE>(key, ciphertext, output)
}

#[no_mangle]
pub extern "C" fn decrypt_note(
shared_key: &[u8; 32],
ciphertext: &[u8; ENCRYPTED_NOTE_SIZE + MAC_SIZE],
output: &mut [u8; ENCRYPTED_NOTE_SIZE],
) -> ParserError {
decrypt::<ENCRYPTED_NOTE_SIZE>(shared_key, ciphertext, output)
}

#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
Expand Down
17 changes: 4 additions & 13 deletions app/src/crypto_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include <string.h>

#include "coin.h"
#include "crypto_helper/chacha.h"
#include "keys_personalizations.h"
#include "rslib.h"
#include "zxformat.h"
Expand Down Expand Up @@ -271,12 +270,7 @@ parser_error_t crypto_decrypt_merkle_note(parser_tx_t *txObj, const uint8_t *m_n

// Decrypt the note encryption keys
uint8_t note_encryption_key[ENCRYPTED_SHARED_KEY_SIZE] = {0};
uint8_t cc_nonce[CHACHA_NONCE_SIZE] = {0};
CHECK_ERROR(chacha(note_encryption_key, sizeof(note_encryption_key), m_note + NOTE_ENCRYPTION_KEYS_OFFSET,
ENCRYPTED_SHARED_KEY_SIZE, encryption_key, cc_nonce, 1));
#if defined(LEDGER_SPECIFIC)
io_seproxyhal_io_heartbeat();
#endif
CHECK_ERROR(decrypt_note_encryption_keys(encryption_key, m_note + NOTE_ENCRYPTION_KEYS_OFFSET, note_encryption_key));
CHECK_APP_CANARY()

// Extract public address and secret key from the note encryption key
Expand All @@ -289,17 +283,14 @@ parser_error_t crypto_decrypt_merkle_note(parser_tx_t *txObj, const uint8_t *m_n
uint8_t shared_key[32] = {0};
const uint8_t *ephemeral_public_key = m_note + VALUE_COMMITMENT_SIZE + NOTE_COMMITMENT_SIZE;
CHECK_ERROR(shared_secret(secret_key, public_address, ephemeral_public_key, shared_key));
#if defined(LEDGER_SPECIFIC)
io_seproxyhal_io_heartbeat();
#endif
CHECK_APP_CANARY()

// Finally decrypt the note
uint8_t plain_text[ENCRYPTED_NOTE_SIZE] = {0};
CHECK_ERROR(chacha(plain_text, sizeof(plain_text), m_note + ENCRYPTED_NOTE_OFFSET, ENCRYPTED_NOTE_SIZE, shared_key,
cc_nonce, 1));
CHECK_ERROR(decrypt_note(shared_key, m_note + ENCRYPTED_NOTE_OFFSET, plain_text));

#if defined(LEDGER_SPECIFIC)
io_seproxyhal_io_heartbeat();
io_seproxyhal_io_heartbeat();
#endif
CHECK_APP_CANARY()
// Fill the txObj with the decrypted note
Expand Down
Loading

0 comments on commit e665fc5

Please sign in to comment.