Skip to content

Commit

Permalink
oracle: cleanup sig verify
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-zaremba committed Aug 10, 2023
1 parent f8d79c0 commit fe92afe
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 76 deletions.
3 changes: 2 additions & 1 deletion contracts/oracle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ crate-type = ["cdylib", "rlib"]
uint.workspace = true
near-sdk.workspace = true
serde_json.workspace = true
ed25519-dalek.workspace = true

cost = { path = "../cost" }
sbt = { path = "../sbt" }
Expand All @@ -23,7 +22,9 @@ sbt = { path = "../sbt" }
rand = "^0.7"
near-primitives.workspace = true
near-crypto.workspace = true
ed25519-dalek.workspace = true

# integration tests
pretty_assertions.workspace = true
anyhow.workspace = true
tokio.workspace = true
Expand Down
77 changes: 3 additions & 74 deletions contracts/oracle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use ed25519_dalek::{PUBLIC_KEY_LENGTH};
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::{LazyOption, UnorderedSet};
use near_sdk::serde::Serialize;
Expand Down Expand Up @@ -299,45 +298,6 @@ impl Contract {
// - fn sbt_renew
}

mod sys {
extern "C" {
pub fn ed25519_verify(
sig_len: u64,
sig_ptr: u64,
msg_len: u64,
msg_ptr: u64,
pub_key_len: u64,
pub_key_ptr: u64,
) -> u64;
}
}

pub fn ed25519_verify(signature: &[u8; 64], message: &[u8], public_key: &[u8; 32]) -> bool {
unsafe {
sys::ed25519_verify(
signature.len() as _,
signature.as_ptr() as _,
message.len() as _,
message.as_ptr() as _,
public_key.len() as _,
public_key.as_ptr() as _,
) == 1
}
}

fn verify_claim(
pubkey: &[u8; PUBLIC_KEY_LENGTH],
claim: Vec<u8>,
claim_sig: &[u8; 64],
) -> Result<(), CtrError> {
let valid = ed25519_verify(claim_sig, &claim, pubkey);
if !valid {
return Err(CtrError::Signature("invalid signature".to_string()))
} else {
Ok(())
}
}

#[near_bindgen]
impl SBTContract for Contract {
fn sbt_metadata(&self) -> ContractMetadata {
Expand All @@ -359,7 +319,7 @@ pub enum CallbackResult<T, E> {
mod checks;

#[cfg(all(test, not(target_arch = "wasm32")))]
mod tests {
pub mod tests {
extern crate ed25519_dalek;
extern crate rand;

Expand All @@ -370,7 +330,7 @@ mod tests {
use ed25519_dalek::{Keypair, Signer};
use rand::rngs::OsRng;

fn b64_encode(data: Vec<u8>) -> String {
pub fn b64_encode(data: Vec<u8>) -> String {
near_sdk::base64::encode(data)
}

Expand Down Expand Up @@ -672,41 +632,10 @@ mod tests {
let claim_bytes = b64_decode("claim_b64", c_str).unwrap();
let signature = b64_decode("sign_b64", sig).unwrap();
let signature: [u8; 64] = signature.try_into().expect("signature must be 64 bytes");
let res = verify_claim(
&k.public.to_bytes(),
claim_bytes,
&signature,
);
let res = verify_claim(&k.public.to_bytes(), claim_bytes, &signature);
assert!(res.is_ok(), "verification result: {:?}", res);
}

#[test]
fn pubkey_near_crypto() {
//let sk = near_crypto::SecretKey::from_str("ed25519:...").unwrap();
let sk = near_crypto::SecretKey::from_random(near_crypto::KeyType::ED25519);
let k = match sk.clone() {
near_crypto::SecretKey::ED25519(k) => ed25519_dalek::Keypair::from_bytes(&k.0).unwrap(),
_ => panic!("expecting ed25519 key"),
};

let pk_bs58 = near_sdk::bs58::encode(k.public).into_string();
let pk_b64 = b64_encode(k.public.as_bytes().to_vec());
let sk_str = near_sdk::bs58::encode(k.secret).into_string();
let sk_str2 = sk.to_string();
println!(
"pubkey_bs58={} pubkey_b64={}\nsecret={} {}",
pk_bs58, pk_b64, sk_str, sk_str2,
);

// let sk2 = near_crypto::SecretKey::from_str(
// "secp256k1:AxynSCWRr2RrBXbzcbykYTo5vPmCkMf35s1D1bXV8P51",
// )
// .unwrap();
// println!("\nsecp: {}, public: {}", sk2, sk2.public_key());

// assert!(false);
}

#[test]
fn claim_serialization() {
let c = mk_claim(1677621259142, "some_111#$!", false);
Expand Down
81 changes: 80 additions & 1 deletion contracts/oracle/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::str::Chars;

use ed25519_dalek::PUBLIC_KEY_LENGTH;
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::{base64, env, AccountId};
use uint::hex;

pub use crate::errors::*;

pub const PUBLIC_KEY_LENGTH: usize = 32;

type CtrResult<T> = Result<T, CtrError>;

#[derive(BorshSerialize, BorshDeserialize)]
Expand Down Expand Up @@ -38,6 +39,52 @@ pub fn pubkey_from_b64(pubkey: String) -> [u8; PUBLIC_KEY_LENGTH] {
pk_bz.try_into().expect("authority pubkey must be 32 bytes")
}

mod sys {
extern "C" {
#[allow(dead_code)]
pub fn ed25519_verify(
sig_len: u64,
sig_ptr: u64,
msg_len: u64,
msg_ptr: u64,
pub_key_len: u64,
pub_key_ptr: u64,
) -> u64;
}
}

#[cfg(not(all(test, not(target_arch = "wasm32"))))]
pub fn ed25519_verify(signature: &[u8; 64], message: &[u8], public_key: &[u8; 32]) -> bool {
unsafe {
sys::ed25519_verify(
signature.len() as _,
signature.as_ptr() as _,
message.len() as _,
message.as_ptr() as _,
public_key.len() as _,
public_key.as_ptr() as _,
) == 1
}
}

#[cfg(all(test, not(target_arch = "wasm32")))]
pub fn ed25519_verify(signature: &[u8; 64], message: &[u8], public_key: &[u8; 32]) -> bool {
return true;
}

pub fn verify_claim(
pubkey: &[u8; PUBLIC_KEY_LENGTH],
claim: Vec<u8>,
claim_sig: &[u8; 64],
) -> Result<(), CtrError> {
let valid = ed25519_verify(claim_sig, &claim, pubkey);
if !valid {
return Err(CtrError::Signature("invalid signature".to_string()));
} else {
Ok(())
}
}

/// only root accounts and implicit accounts are supported
pub(crate) fn is_supported_account(account: Chars) -> bool {
let mut num_dots = 0;
Expand Down Expand Up @@ -106,4 +153,36 @@ mod tests {
FromHexError::InvalidHexCharacter { c: 'w', index: 1 },
);
}

#[test]
fn check_pub_key_len() {
assert_eq!(ed25519_dalek::PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH);
}

#[test]
fn pubkey_near_crypto() {
//let sk = near_crypto::SecretKey::from_str("ed25519:...").unwrap();
let sk = near_crypto::SecretKey::from_random(near_crypto::KeyType::ED25519);
let k = match sk.clone() {
near_crypto::SecretKey::ED25519(k) => ed25519_dalek::Keypair::from_bytes(&k.0).unwrap(),
_ => panic!("expecting ed25519 key"),
};

let pk_bs58 = near_sdk::bs58::encode(k.public).into_string();
let pk_b64 = near_sdk::base64::encode(k.public.as_bytes().to_vec());
let sk_str = near_sdk::bs58::encode(k.secret).into_string();
let sk_str2 = sk.to_string();
println!(
"pubkey_bs58={} pubkey_b64={}\nsecret={} {}",
pk_bs58, pk_b64, sk_str, sk_str2,
);

// let sk2 = near_crypto::SecretKey::from_str(
// "secp256k1:AxynSCWRr2RrBXbzcbykYTo5vPmCkMf35s1D1bXV8P51",
// )
// .unwrap();
// println!("\nsecp: {}, public: {}", sk2, sk2.public_key());

// assert!(false);
}
}

0 comments on commit fe92afe

Please sign in to comment.