-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate slots to U256 #328
Changes from 12 commits
a968946
e65aa8a
cc030db
56f0e3c
e55b719
312c1d4
38962c9
b9412e5
13d5e93
91a2d78
6bf0102
655665e
a367ae4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
use dep::std::ops::Add; | ||
use crate::misc::types::Bytes32; | ||
use crate::misc::bytes32::field_to_bytes32; | ||
use crate::misc::arrays::memcpy_up_to_length; | ||
|
||
global uint128_overflow_value = 340282366920938463463374607431768211456; // 2^128 | ||
|
||
|
@@ -19,6 +22,38 @@ impl U256 { | |
fn one() -> Self { | ||
Self { high: U128::from_integer(0), low: U128::from_integer(1) } | ||
} | ||
|
||
fn from_field(field: Field) -> Self { | ||
U256::from(field_to_bytes32(field)) | ||
} | ||
} | ||
|
||
impl From<Bytes32> for U256 { | ||
fn from(bytes: Bytes32) -> Self { | ||
let mut high_bytes = [0; 16]; | ||
memcpy_up_to_length(&mut high_bytes, bytes, 16, 16); | ||
let high = U128::from_le_bytes(high_bytes); | ||
|
||
let mut low_bytes = [0; 16]; | ||
memcpy_up_to_length(&mut low_bytes, bytes, 0, 16); | ||
let low = U128::from_le_bytes(low_bytes); | ||
|
||
U256::new(high, low) | ||
} | ||
} | ||
|
||
impl Into<Bytes32> for U256 { | ||
fn into(self) -> Bytes32 { | ||
let mut bytes = [0; 32]; | ||
memcpy_up_to_length(&mut bytes, self.low.to_le_bytes(), 0, 16); | ||
|
||
let high_bytes = self.high.to_le_bytes(); | ||
for i in 0..16 { | ||
bytes[i + 16] = high_bytes[i]; | ||
} | ||
|
||
bytes | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not inline? |
||
} | ||
|
||
impl Eq for U256 { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,64 @@ fn zero_and_one() { | |
assert_eq(one.low, U128::one()); | ||
} | ||
|
||
mod from_bytes32 { | ||
use crate::uint256::U256; | ||
global high = U128::from_integer(0x10000000000000000000000000000000); | ||
global low = U128::zero(); | ||
global limit = U128::from_integer(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | ||
|
||
global big_number = U256 { high, low }; | ||
global limit_u256 = U256 {high: limit, low:limit}; | ||
|
||
#[test] | ||
fn zero() { | ||
let bytes = [0x00; 32]; | ||
assert_eq(U256::from(bytes), U256::zero()); | ||
} | ||
|
||
#[test] | ||
fn success() { | ||
let mut bytes = [0x00; 32]; | ||
bytes[31] = 0x10; | ||
assert_eq(U256::from(bytes), big_number); | ||
} | ||
|
||
#[test] | ||
fn u256_limit() { | ||
let bytes = [0xff; 32]; | ||
assert_eq(U256::from(bytes), limit_u256); | ||
} | ||
} | ||
|
||
mod into_bytes32 { | ||
use crate::uint256::U256; | ||
global high = U128::from_integer(0x10000000000000000000000000000000); | ||
global low = U128::zero(); | ||
global limit = U128::from_integer(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | ||
|
||
global big_number = U256 { high, low }; | ||
global limit_u256 = U256 {high: limit, low:limit}; | ||
|
||
#[test] | ||
fn zero() { | ||
let bytes = [0x00; 32]; | ||
assert_eq(U256::into(U256::zero()), bytes); | ||
} | ||
|
||
#[test] | ||
fn success() { | ||
let mut bytes = [0x00; 32]; | ||
bytes[31] = 0x10; | ||
assert_eq(U256::into(big_number), bytes); | ||
} | ||
|
||
#[test] | ||
fn u256_limit() { | ||
let bytes = [0xff; 32]; | ||
assert_eq(U256::into(limit_u256), bytes); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some more tests pls :) |
||
|
||
#[test] | ||
fn eq() { | ||
assert_eq(big_number, big_number); | ||
|
@@ -47,23 +105,32 @@ fn not_eq() { | |
assert(big_number != big_number3); | ||
} | ||
|
||
#[test] | ||
fn sum() { | ||
let sum = big_number + big_number; | ||
mod trait_add { | ||
use crate::uint256::U256; | ||
global high = U128::from_integer(0x10000000000000000000000000000000); | ||
global low = U128::zero(); | ||
global limit = U128::from_integer(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); | ||
|
||
assert_eq(sum, U256 { high: U128::from_integer(0x20000000000000000000000000000000), low }); | ||
} | ||
global big_number = U256 { high, low }; | ||
global limit_u256 = U256 {high: limit, low:limit}; | ||
|
||
#[test] | ||
fn sum_with_carry() { | ||
let big_number = U256 { high, low: limit }; | ||
let sum = big_number + U256::one(); | ||
#[test] | ||
fn sum() { | ||
let sum = big_number + big_number; | ||
|
||
assert_eq(sum, U256 { high: U128::from_integer(0x10000000000000000000000000000001), low }); | ||
} | ||
assert_eq(sum, U256 { high: U128::from_integer(0x20000000000000000000000000000000), low }); | ||
} | ||
|
||
#[test] | ||
fn sum_with_carry() { | ||
let big_number = U256 { high, low: limit }; | ||
let sum = big_number + U256::one(); | ||
|
||
assert_eq(sum, U256 { high: U128::from_integer(0x10000000000000000000000000000001), low }); | ||
} | ||
|
||
#[test(should_fail_with="attempt to add with overflow")] | ||
fn sum_overflow() { | ||
let limit_number = U256 { high: limit, low: limit }; | ||
let _ = limit_number + U256::one(); | ||
#[test(should_fail_with="attempt to add with overflow")] | ||
fn sum_overflow() { | ||
let _ = limit_u256 + U256::one(); | ||
} | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unnecessary import |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not inline?