Skip to content

Commit

Permalink
support perpetual-contract branch of circuit
Browse files Browse the repository at this point in the history
  • Loading branch information
Fred0327 committed Oct 31, 2023
1 parent 7c96aa9 commit 8e4215b
Show file tree
Hide file tree
Showing 37 changed files with 1,979 additions and 358 deletions.
2 changes: 2 additions & 0 deletions binding_tests/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func TestSignOrderMatching(t *testing.T) {
*big.NewInt(323289),
*big.NewInt(135),
true,
false,
2,
5,
nil,
Expand All @@ -165,6 +166,7 @@ func TestSignOrderMatching(t *testing.T) {
*big.NewInt(323355),
*big.NewInt(135),
false,
false,
2,
5,
nil,
Expand Down
1 change: 1 addition & 0 deletions bindings/sdk/src/ffi.udl
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ interface Order {
BigUint amount,
BigUint price,
boolean is_sell,
boolean has_subsidy,
u8 fee_ratio1,
u8 fee_ratio2,
ZkLinkSignature ?signature
Expand Down
1 change: 1 addition & 0 deletions bindings/sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use zklink_sdk_signers::zklink_signer::signature::{PackedSignature, ZkLinkSignat

use zklink_sdk_types::basic_types::tx_hash::TxHash;
use zklink_sdk_types::basic_types::zklink_address::ZkLinkAddress;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::basic_types::{
AccountId, BigUint, BlockNumber, ChainId, EthBlockId, Nonce, PairId, PriorityOpId, SlotId,
SubAccountId, TimeStamp, TokenId,
Expand Down
2 changes: 1 addition & 1 deletion interface/src/sign_change_pubkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ use std::sync::Arc;
use zklink_sdk_signers::eth_signer::packed_eth_signature::PackedEthSignature;
use zklink_sdk_signers::eth_signer::pk_signer::EthSigner;
use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::basic_types::ZkLinkAddress;
#[cfg(not(feature = "ffi"))]
use zklink_sdk_types::prelude::TxSignature;
#[cfg(feature = "ffi")]
use zklink_sdk_types::tx_type::change_pubkey::Create2Data;
use zklink_sdk_types::tx_type::change_pubkey::{ChangePubKey, ChangePubKeyAuthData};
use zklink_sdk_types::tx_type::TxTrait;

#[cfg(not(feature = "ffi"))]
pub fn sign_change_pubkey(
Expand Down
4 changes: 2 additions & 2 deletions interface/src/sign_forced_exit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
use std::sync::Arc;
use zklink_sdk_signers::zklink_signer::error::ZkSignerError;
use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::prelude::TxSignature;
use zklink_sdk_types::tx_type::forced_exit::ForcedExit;
use zklink_sdk_types::tx_type::TxTrait;

pub fn sign_forced_exit(
zklink_signer: &ZkLinkSigner,
Expand Down Expand Up @@ -52,7 +52,7 @@ mod tests {
withdraw_to_l1: false,
timestamp: TimeStamp(1649749979),
};
let tx = ForcedExit::new(builder);
let tx = builder.build();

let signature = sign_forced_exit(&zk_signer, tx).unwrap();
assert!(signature.eth_signature.is_none());
Expand Down
2 changes: 1 addition & 1 deletion interface/src/sign_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
use std::sync::Arc;
use zklink_sdk_signers::zklink_signer::error::ZkSignerError;
use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::tx_type::order_matching::Order;
use zklink_sdk_types::tx_type::TxTrait;
#[cfg(not(feature = "ffi"))]
pub fn sign(order: &mut Order, signer: &ZkLinkSigner) -> Result<(), ZkSignerError> {
let bytes = order.get_bytes();
Expand Down
2 changes: 1 addition & 1 deletion interface/src/sign_order_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
use std::sync::Arc;
use zklink_sdk_signers::zklink_signer::error::ZkSignerError;
use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::prelude::TxSignature;
use zklink_sdk_types::tx_type::order_matching::OrderMatching;
use zklink_sdk_types::tx_type::TxTrait;

pub fn sign_order_matching(
zklink_signer: &ZkLinkSigner,
Expand Down
4 changes: 2 additions & 2 deletions interface/src/sign_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use crate::error::SignError;
use std::sync::Arc;
use zklink_sdk_signers::eth_signer::pk_signer::EthSigner;
use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::prelude::TxSignature;
use zklink_sdk_types::tx_type::transfer::Transfer;
use zklink_sdk_types::tx_type::TxTrait;

pub fn sign_transfer(
eth_signer: &EthSigner,
Expand Down Expand Up @@ -57,7 +57,7 @@ mod tests {
nonce: Nonce(1),
timestamp: TimeStamp(1646101085),
};
let tx = Transfer::new(builder);
let tx = builder.build();

let signature = sign_transfer(&eth_signer, &zk_signer, tx, "USD").unwrap();
let eth_sign = signature
Expand Down
6 changes: 3 additions & 3 deletions interface/src/sign_withdraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use crate::error::SignError;
use std::sync::Arc;
use zklink_sdk_signers::eth_signer::pk_signer::EthSigner;
use zklink_sdk_signers::zklink_signer::pk_signer::ZkLinkSigner;
#[cfg(feature = "ffi")]
use zklink_sdk_types::basic_types::GetBytes;
use zklink_sdk_types::prelude::TxSignature;
use zklink_sdk_types::tx_type::withdraw::Withdraw;
#[cfg(feature = "ffi")]
use zklink_sdk_types::tx_type::TxTrait;
use zklink_sdk_types::tx_type::ZkSignatureTrait;

pub fn sign_withdraw(
Expand Down Expand Up @@ -61,7 +61,7 @@ mod tests {
withdraw_fee_ratio: 50,
timestamp: TimeStamp(1649749979),
};
let tx = Withdraw::new(builder);
let tx = builder.build();
let eth_signer = eth_pk.into();
let zk_signer = ZkLinkSigner::new_from_eth_signer(&eth_signer).unwrap();
let signature = sign_withdraw(&eth_signer, &zk_signer, tx, "USD").unwrap();
Expand Down
35 changes: 33 additions & 2 deletions signers/src/zklink_signer/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub(crate) fn rescue_hash_elements(input: &[Fr]) -> Fr {
})
}

pub(crate) fn rescue_hash_tx_msg(msg: &[u8]) -> Vec<u8> {
pub fn rescue_hash_tx_msg(msg: &[u8]) -> Vec<u8> {
let mut msg_bits = bytes_into_be_bits(msg);
assert!(msg_bits.len() <= PAD_MSG_BEFORE_HASH_BITS_LEN);
msg_bits.resize(PAD_MSG_BEFORE_HASH_BITS_LEN, false);
Expand All @@ -100,9 +100,40 @@ fn get_bits_le_fixed(fr: &Fr, size: usize) -> Vec<bool> {
}

pub fn rescue_hash_orders(msg: &[u8]) -> Vec<u8> {
assert_eq!(msg.len(), 178);
let msg_bits = bytes_into_be_bits(msg);
let hash_fr = rescue_hash_fr(msg_bits);
let hash_bits = get_bits_le_fixed(&hash_fr, 248);
pack_bits_into_bytes_le(&hash_bits)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_rescue_hash_tx_msg() {
let msg = [1u8, 2u8, 3u8, 4u8];
let hash = rescue_hash_tx_msg(&msg);

assert_eq!(
hash,
vec![
249, 154, 208, 123, 96, 89, 132, 235, 231, 63, 56, 200, 153, 131, 27, 183, 128, 71,
26, 245, 208, 120, 49, 246, 233, 72, 230, 84, 66, 150, 170, 27
]
);
}

#[test]
fn test_rescue_hash_orders() {
let msg = [1u8, 2, 3, 4, 5];
let hash = rescue_hash_orders(&msg);
assert_eq!(
hash,
vec![
88, 229, 220, 95, 31, 216, 185, 113, 100, 149, 78, 174, 140, 96, 206, 176, 152, 81,
237, 23, 246, 77, 252, 113, 151, 247, 40, 110, 136, 240, 36
]
);
}
}
8 changes: 4 additions & 4 deletions types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ethers = "2.0.10"
ethers = "2.0"
hex = "0.4"
num = { version = "0.4.0", features = ["serde"] }
serde = "1.0.137"
serde_json = "1.0.0"
num = { version = "0.4", features = ["serde"] }
serde = "1.0"
serde_json = "1.0"
thiserror = "1.0"
validator = { version = "0.15", features = ["derive"] }
zklink_sdk_signers = { path = "../signers" }
Expand Down
54 changes: 54 additions & 0 deletions types/src/basic_types/bit_convert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
pub struct BitConvert;

impl BitConvert {
/// Сonverts a set of bits to a set of bytes in direct order.
pub fn into_bytes(bits: Vec<bool>) -> Vec<u8> {
assert_eq!(bits.len() % 8, 0);
let mut message_bytes: Vec<u8> = vec![];

let byte_chunks = bits.chunks(8);
for byte_chunk in byte_chunks {
let mut byte = 0u8;
for (i, bit) in byte_chunk.iter().enumerate() {
if *bit {
byte |= 1 << i;
}
}
message_bytes.push(byte);
}

message_bytes
}

/// Сonverts a set of bits to a set of bytes in reverse order for each byte.
pub fn into_bytes_ordered(bits: Vec<bool>) -> Vec<u8> {
assert_eq!(bits.len() % 8, 0);
let mut message_bytes: Vec<u8> = vec![];

let byte_chunks = bits.chunks(8);
for byte_chunk in byte_chunks {
let mut byte = 0u8;
for (i, bit) in byte_chunk.iter().rev().enumerate() {
if *bit {
byte |= 1 << i;
}
}
message_bytes.push(byte);
}

message_bytes
}

/// Сonverts a set of Big Endian bytes to a set of bits.
pub fn from_be_bytes(bytes: &[u8]) -> Vec<bool> {
let mut bits = vec![];
for byte in bytes {
let mut temp = *byte;
for _ in 0..8 {
bits.push(temp & 0x80 == 0x80);
temp <<= 1;
}
}
bits
}
}
106 changes: 70 additions & 36 deletions types/src/basic_types/float_convert.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,7 @@
use crate::basic_types::bit_convert::BitConvert;
use crate::error::TypeError as Error;
use num::{BigUint, ToPrimitive};

pub struct BitConvert;

impl BitConvert {
/// Сonverts a set of bits to a set of bytes in reverse order for each byte.
#[allow(clippy::wrong_self_convention)]
pub fn into_bytes_ordered(bits: Vec<bool>) -> Vec<u8> {
assert_eq!(bits.len() % 8, 0);
let mut message_bytes: Vec<u8> = vec![];

let byte_chunks = bits.chunks(8);
for byte_chunk in byte_chunks {
let mut byte = 0u8;
for (i, bit) in byte_chunk.iter().rev().enumerate() {
if *bit {
byte |= 1 << i;
}
}
message_bytes.push(byte);
}

message_bytes
}

/// Сonverts a set of Big Endian bytes to a set of bits.
pub fn from_be_bytes(bytes: &[u8]) -> Vec<bool> {
let mut bits = vec![];
for byte in bytes {
let mut temp = *byte;
for _ in 0..8 {
bits.push(temp & 0x80 == 0x80);
temp <<= 1;
}
}
bits
}
}
/// Convert Uint to the floating-point and vice versa.
pub struct FloatConversions;

Expand All @@ -51,6 +16,17 @@ impl FloatConversions {
BitConvert::into_bytes_ordered(vec)
}

/// Packs a BigUint less than 2 ^ 128 to a floating-point number with an exponent base = 10 that is greater or equal to initial number.
/// Can lose accuracy with small parameters `exponent_len` and `mantissa_len`.
pub fn pack_up(number: &BigUint, exponent_len: usize, mantissa_len: usize) -> Vec<u8> {
let uint = number.to_u128().expect("Only u128 allowed");

let mut vec =
Self::to_float_up(uint, exponent_len, mantissa_len, 10).expect("packing error");
vec.reverse();
BitConvert::into_bytes_ordered(vec)
}

/// Unpacks a floating point number with the given parameters.
/// Returns `None` for numbers greater than 2 ^ 128.
pub fn unpack(data: &[u8], exponent_len: usize, mantissa_len: usize) -> Option<u128> {
Expand Down Expand Up @@ -131,6 +107,64 @@ impl FloatConversions {
}
};

// encode into bits. First bits of mantissa in LE order
let mut encoding = Vec::with_capacity(exponent_length + mantissa_length);

for i in 0..exponent_length {
if exponent & (1 << i) != 0 {
encoding.push(true);
} else {
encoding.push(false);
}
}

for i in 0..mantissa_length {
if mantissa & (1 << i) != 0 {
encoding.push(true);
} else {
encoding.push(false);
}
}

debug_assert_eq!(encoding.len(), exponent_length + mantissa_length);
Ok(encoding)
}

/// Packs a u128 to a floating-point number with the given parameters that is greater or equal to integer.
/// Can lose accuracy with small parameters `exponent_len` and `mantissa_len`.
#[allow(clippy::wrong_self_convention)]
pub fn to_float_up(
integer: u128,
exponent_length: usize,
mantissa_length: usize,
exponent_base: u32,
) -> Result<Vec<bool>, Error> {
let exponent_base = u128::from(exponent_base);

let max_power = (1 << exponent_length) - 1;

let max_exponent = exponent_base.saturating_pow(max_power);

let max_mantissa = (1u128 << mantissa_length) - 1;

if integer > (max_mantissa.saturating_mul(max_exponent)) {
return Err(Error::TooBigInteger);
}

// The algortihm is as follows: calculate minimal exponent
// such that integer <= max_mantissa * exponent_base ^ exponent,
// then mantissa is calculated as integer divided by exponent_base ^ exponent and rounded up
let mut exponent: usize = 0;
let mut exponent_temp: u128 = 1;
while integer > max_mantissa * exponent_temp {
exponent_temp *= exponent_base;
exponent += 1;
}
let mut mantissa = integer / exponent_temp;
if integer % exponent_temp != 0 {
mantissa += 1;
}

// encode into bits. First bits of mantissa in LE order

let mut encoding = Vec::with_capacity(exponent_length + mantissa_length);
Expand Down
Loading

0 comments on commit 8e4215b

Please sign in to comment.