Skip to content

Commit

Permalink
Update starknet-crypto to 0.7.3 (#1892)
Browse files Browse the repository at this point in the history
* Update starknet-crypto to 0.7.3

* try to fix wasm
  • Loading branch information
edg-l authored Dec 12, 2024
1 parent b416f80 commit 43c6d50
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 96 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#### Upcoming Changes

* Update starknet-crypto to 0.7.3, removing the old FieldElement completly in favour of the new Felt (that is Copy).

* chore: update the cairo-vm version used in the readme

* chore: update cairo-lang dependencies to 2.9.2
Expand Down
44 changes: 11 additions & 33 deletions Cargo.lock

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

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ hex = { version = "0.4.3", default-features = false }
bincode = { version = "2.0.0-rc.3", default-features = false, features = [
"serde",
] }
starknet-crypto = { version = "0.6.1", default-features = false, features = [
starknet-crypto = { version = "0.7.3", default-features = false, features = [
"signature-display",
"alloc",
] }
Expand All @@ -55,8 +55,8 @@ nom = { version = "7", default-features = false }
sha2 = { version = "0.10.7", features = ["compress"], default-features = false }
generic-array = { version = "0.14.7", default-features = false }
keccak = { version = "0.1.2", default-features = false }
hashbrown = { version = "0.14.0", features = ["serde"] }
anyhow = { version = "1.0.69", default-features = false }
hashbrown = { version = "0.15.2", features = ["serde"] }
anyhow = { version = "1.0.94", default-features = false }
thiserror-no-std = { version = "2.0.2", default-features = false }

bitvec = { version = "1", default-features = false, features = ["alloc"] }
Expand Down
2 changes: 2 additions & 0 deletions vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ num-prime = { version = "0.4.3", features = ["big-int"] }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3.34"
# The js feature needs to be enabled
getrandom = { version = "*", features = ["js"]}

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
iai-callgrind = "0.3.1"
Expand Down
70 changes: 26 additions & 44 deletions vm/src/program_hash.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use starknet_crypto::{pedersen_hash, FieldElement};
use starknet_crypto::pedersen_hash;

use crate::Felt252;

Expand All @@ -7,7 +7,7 @@ use crate::types::builtin_name::BuiltinName;
use crate::types::relocatable::MaybeRelocatable;
use crate::vm::runners::cairo_pie::StrippedProgram;

type HashFunction = fn(&FieldElement, &FieldElement) -> FieldElement;
type HashFunction = fn(&Felt252, &Felt252) -> Felt252;

#[derive(thiserror_no_std::Error, Debug)]
pub enum HashChainError {
Expand All @@ -27,84 +27,66 @@ pub enum ProgramHashError {

#[error("Invalid program data: data contains relocatable(s)")]
InvalidProgramData,

/// Conversion from Felt252 to FieldElement failed. This is unlikely to happen
/// unless the implementation of Felt252 changes and this code is not updated properly.
#[error("Conversion from Felt252 to FieldElement failed")]
Felt252ToFieldElementConversionFailed,
}

/// Computes a hash chain over the data, in the following order:
/// h(data[0], h(data[1], h(..., h(data[n-2], data[n-1])))).
/// [cairo_lang reference](https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/cairo/common/hash_chain.py#L6)
fn compute_hash_chain<'a, I>(
data: I,
hash_func: HashFunction,
) -> Result<FieldElement, HashChainError>
fn compute_hash_chain<'a, I>(data: I, hash_func: HashFunction) -> Result<Felt252, HashChainError>
where
I: Iterator<Item = &'a FieldElement> + DoubleEndedIterator,
I: Iterator<Item = &'a Felt252> + DoubleEndedIterator,
{
match data.copied().rev().reduce(|x, y| hash_func(&y, &x)) {
Some(result) => Ok(result),
None => Err(HashChainError::EmptyData),
}
}

/// Creates an instance of `FieldElement` from a builtin name.
/// Creates an instance of `Felt252` from a builtin name.
///
/// Converts the builtin name to bytes then attempts to create a field element from
/// these bytes. This function will fail if the builtin name is over 31 characters.
fn builtin_name_to_field_element(
builtin_name: &BuiltinName,
) -> Result<FieldElement, ProgramHashError> {
fn builtin_name_to_field_element(builtin_name: &BuiltinName) -> Result<Felt252, ProgramHashError> {
// The Python implementation uses the builtin name without suffix
FieldElement::from_byte_slice_be(builtin_name.to_str().as_bytes())
.map_err(|_| ProgramHashError::InvalidProgramBuiltin(builtin_name.to_str()))
}

/// The `value: FieldElement` is `pub(crate)` and there is no accessor.
/// This function converts a `Felt252` to a `FieldElement` using a safe, albeit inefficient,
/// method.
fn felt_to_field_element(felt: &Felt252) -> Result<FieldElement, ProgramHashError> {
let bytes = felt.to_bytes_be();
FieldElement::from_bytes_be(&bytes)
.map_err(|_e| ProgramHashError::Felt252ToFieldElementConversionFailed)
Ok(Felt252::from_bytes_be_slice(
builtin_name.to_str().as_bytes(),
))
}

/// Converts a `MaybeRelocatable` into a `FieldElement` value.
/// Converts a `MaybeRelocatable` into a `Felt252` value.
///
/// Returns `InvalidProgramData` if `maybe_relocatable` is not an integer
fn maybe_relocatable_to_field_element(
maybe_relocatable: &MaybeRelocatable,
) -> Result<FieldElement, ProgramHashError> {
let felt = maybe_relocatable
) -> Result<Felt252, ProgramHashError> {
maybe_relocatable
.get_int_ref()
.ok_or(ProgramHashError::InvalidProgramData)?;
felt_to_field_element(felt)
.copied()
.ok_or(ProgramHashError::InvalidProgramData)
}

/// Computes the Pedersen hash of a program.
/// [(cairo_lang reference)](https://github.com/starkware-libs/cairo-lang/blob/efa9648f57568aad8f8a13fbf027d2de7c63c2c0/src/starkware/cairo/bootloaders/hash_program.py#L11)
pub fn compute_program_hash_chain(
program: &StrippedProgram,
bootloader_version: usize,
) -> Result<FieldElement, ProgramHashError> {
) -> Result<Felt252, ProgramHashError> {
let program_main = program.main;
let program_main = FieldElement::from(program_main);
let program_main = Felt252::from(program_main);

// Convert builtin names to field elements
let builtin_list: Result<Vec<FieldElement>, _> = program
let builtin_list: Result<Vec<Felt252>, _> = program
.builtins
.iter()
.map(builtin_name_to_field_element)
.collect();
let builtin_list = builtin_list?;

let program_header = vec![
FieldElement::from(bootloader_version),
Felt252::from(bootloader_version),
program_main,
FieldElement::from(program.builtins.len()),
Felt252::from(program.builtins.len()),
];

let program_data: Result<Vec<_>, _> = program
Expand All @@ -115,7 +97,7 @@ pub fn compute_program_hash_chain(
let program_data = program_data?;

let data_chain_len = program_header.len() + builtin_list.len() + program_data.len();
let data_chain_len_vec = vec![FieldElement::from(data_chain_len)];
let data_chain_len_vec = vec![Felt252::from(data_chain_len)];

// Prepare a chain of iterators to feed to the hash function
let data_chain = [
Expand All @@ -140,14 +122,14 @@ mod tests {

#[test]
fn test_compute_hash_chain() {
let data: Vec<FieldElement> = vec![
FieldElement::from(1u64),
FieldElement::from(2u64),
FieldElement::from(3u64),
let data: Vec<Felt252> = vec![
Felt252::from(1u64),
Felt252::from(2u64),
Felt252::from(3u64),
];
let expected_hash = pedersen_hash(
&FieldElement::from(1u64),
&pedersen_hash(&FieldElement::from(2u64), &FieldElement::from(3u64)),
&Felt252::from(1u64),
&pedersen_hash(&Felt252::from(2u64), &Felt252::from(3u64)),
);
let computed_hash = compute_hash_chain(data.iter(), pedersen_hash)
.expect("Hash computation failed unexpectedly");
Expand Down
27 changes: 11 additions & 16 deletions vm/src/vm/runners/builtin_runner/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::math_utils::div_mod;
use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*, rc::Rc};

use crate::types::builtin_name::BuiltinName;
use crate::types::errors::math_errors::MathError;
use crate::types::instance_definitions::ecdsa_instance_def::CELLS_PER_SIGNATURE;
use crate::vm::errors::runner_errors::RunnerError;
use crate::vm::runners::cairo_pie::BuiltinAdditionalData;
Expand All @@ -22,7 +21,7 @@ use lazy_static::lazy_static;
use num_bigint::{BigInt, Sign};
use num_integer::div_ceil;
use num_traits::{Num, One};
use starknet_crypto::{verify, FieldElement, Signature};
use starknet_crypto::{verify, Signature};

lazy_static! {
static ref EC_ORDER: BigInt = BigInt::from_str_radix(
Expand Down Expand Up @@ -60,8 +59,8 @@ impl SignatureBuiltinRunner {
let r_be_bytes = r.to_bytes_be();
let s_be_bytes = s.to_bytes_be();
let (r_felt, s_felt) = (
FieldElement::from_bytes_be(&r_be_bytes).map_err(|_| MathError::ByteConversionError)?,
FieldElement::from_bytes_be(&s_be_bytes).map_err(|_| MathError::ByteConversionError)?,
Felt252::from_bytes_be(&r_be_bytes),
Felt252::from_bytes_be(&s_be_bytes),
);

let signature = Signature {
Expand Down Expand Up @@ -127,11 +126,9 @@ impl SignatureBuiltinRunner {
.get(&pubkey_addr)
.ok_or_else(|| MemoryError::SignatureNotFound(Box::new(pubkey_addr)))?;

let public_key = FieldElement::from_bytes_be(&pubkey.to_bytes_be())
.map_err(|_| MathError::ByteConversionError)?;
let public_key = Felt252::from_bytes_be(&pubkey.to_bytes_be());
let (r, s) = (signature.r, signature.s);
let message = FieldElement::from_bytes_be(&msg.to_bytes_be())
.map_err(|_| MathError::ByteConversionError)?;
let message = Felt252::from_bytes_be(&msg.to_bytes_be());
match verify(&public_key, &message, &r, &s) {
Ok(true) => Ok(vec![]),
_ => Err(MemoryError::InvalidSignature(Box::new((
Expand Down Expand Up @@ -198,10 +195,8 @@ impl SignatureBuiltinRunner {
self.signatures.borrow_mut().insert(
*addr,
Signature {
r: FieldElement::from_bytes_be(&r.to_bytes_be())
.map_err(|_| MathError::ByteConversionError)?,
s: FieldElement::from_bytes_be(&s.to_bytes_be())
.map_err(|_| MathError::ByteConversionError)?,
r: Felt252::from_bytes_be(&r.to_bytes_be()),
s: Felt252::from_bytes_be(&s.to_bytes_be()),
},
);
}
Expand Down Expand Up @@ -523,8 +518,8 @@ mod tests {
let signatures = HashMap::from([(
Relocatable::from((4, 0)),
Signature {
r: FieldElement::from_dec_str("45678").unwrap(),
s: FieldElement::from_dec_str("1239").unwrap(),
r: Felt252::from_dec_str("45678").unwrap(),
s: Felt252::from_dec_str("1239").unwrap(),
},
)]);
builtin.signatures = Rc::new(RefCell::new(signatures));
Expand All @@ -544,8 +539,8 @@ mod tests {
let signatures = HashMap::from([(
Relocatable::from((0, 0)),
Signature {
r: FieldElement::from_dec_str("45678").unwrap(),
s: FieldElement::from_dec_str("1239").unwrap(),
r: Felt252::from_dec_str("45678").unwrap(),
s: Felt252::from_dec_str("1239").unwrap(),
},
)]);
builtin_a.signatures = Rc::new(RefCell::new(signatures));
Expand Down

0 comments on commit 43c6d50

Please sign in to comment.