extern crate alloc;
use crate::helper::random_bytes;
use alloc::{string::String, vec::Vec};
use libsecp256k1::curve::{Affine, Field, Jacobian, Scalar};
use tiny_keccak::{Hasher, Keccak};
pub trait AffineExtend {
fn compose(x: &Field, y: &Field) -> Self;
fn from_jacobian(j: &Jacobian) -> Self;
fn to_hex_string(&self) -> String;
fn keccak256(&self) -> [u8; 32];
}
pub trait ScalarExtend {
fn from_bytes(bytes: &[u8]) -> Self;
fn randomize() -> Self;
fn keccak256(a: &Vec<u8>) -> Self;
fn gt(&self, b: &Scalar) -> bool;
fn gte(&self, b: &Scalar) -> bool;
}
impl AffineExtend for Affine {
fn compose(x: &Field, y: &Field) -> Self {
let mut r = Affine::default();
r.set_xy(x, y);
r.x.normalize();
r.y.normalize();
r
}
fn to_hex_string(&self) -> String {
hex::encode([self.x.b32(), self.y.b32()].concat())
}
fn keccak256(&self) -> [u8; 32] {
let mut output = [0u8; 32];
let mut hasher = Keccak::v256();
hasher.update(self.x.b32().as_ref());
hasher.update(self.y.b32().as_ref());
hasher.finalize(&mut output);
output
}
fn from_jacobian(j: &Jacobian) -> Self {
let mut ra = Affine::from_gej(j);
ra.x.normalize();
ra.y.normalize();
ra
}
}
impl ScalarExtend for Scalar {
fn from_bytes(bytes: &[u8]) -> Self {
if bytes.len() > 32 {
panic!("Bytes length must be less than 32")
}
let mut tmp_bytes = [0u8; 32];
tmp_bytes[0..bytes.len()].copy_from_slice(bytes);
let mut r = Scalar::default();
r.set_b32(&tmp_bytes).unwrap_u8();
r
}
fn gt(&self, b: &Scalar) -> bool {
for i in (0..self.0.len()).rev() {
if self.0[i] < b.0[i] {
return false;
}
if self.0[i] > b.0[i] {
return true;
}
}
false
}
fn gte(&self, b: &Scalar) -> bool {
for i in (0..self.0.len()).rev() {
if self.0[i] < b.0[i] {
return false;
}
if self.0[i] > b.0[i] {
return true;
}
}
true
}
fn keccak256(a: &Vec<u8>) -> Self {
let mut output = [0u8; 32];
let mut hasher = Keccak::v256();
hasher.update(a.as_slice());
hasher.finalize(&mut output);
Self::from_bytes(&output)
}
fn randomize() -> Self {
let mut buf = [0u8; 32];
random_bytes(&mut buf);
Self::from_bytes(&buf)
}
}