mirror of
https://github.com/pezkuwichain/bizinikiwi-bn.git
synced 2026-04-21 23:48:04 +00:00
g1 from compressed api
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
target
|
||||
Cargo.lock
|
||||
.idea
|
||||
@@ -20,6 +20,8 @@ rand = { version = "0.5", features = ["i128_support"] }
|
||||
rustc-serialize = { version = "0.3", optional = true }
|
||||
byteorder = { version = "1.0", features = ["i128"] }
|
||||
crunchy = "0.2.1"
|
||||
lazy_static = "*"
|
||||
rustc-hex = "2"
|
||||
|
||||
[dev-dependencies.bincode]
|
||||
version = "0.6"
|
||||
|
||||
@@ -240,6 +240,44 @@ field_impl!(
|
||||
0x9ede7d651eca6ac987d20782e4866389
|
||||
);
|
||||
|
||||
lazy_static! {
|
||||
|
||||
static ref FQ: U256 = U256::from([
|
||||
0x3c208c16d87cfd47,
|
||||
0x97816a916871ca8d,
|
||||
0xb85045b68181585d,
|
||||
0x30644e72e131a029
|
||||
]);
|
||||
|
||||
static ref FQ_MINUS3_DIV4: Fq =
|
||||
Fq::new(3.into()).expect("3 is a valid field element and static; qed").neg() *
|
||||
Fq::new(4.into()).expect("4 is a valid field element and static; qed").inverse()
|
||||
.expect("4 has inverse in Fq and is static; qed");
|
||||
|
||||
static ref FQ_MINUS1_DIV2: Fq =
|
||||
Fq::new(1.into()).expect("1 is a valid field element and static; qed").neg() *
|
||||
Fq::new(2.into()).expect("2 is a valid field element and static; qed").inverse()
|
||||
.expect("2 has inverse in Fq and is static; qed");
|
||||
|
||||
}
|
||||
|
||||
impl Fq {
|
||||
pub fn sqrt(&self) -> Option<Self> {
|
||||
let a1 = self.pow(*FQ_MINUS3_DIV4);
|
||||
let a1a = a1 * *self;
|
||||
let a0 = a1 * (a1a);
|
||||
|
||||
let mut am1 = *FQ;
|
||||
am1.sub(&1.into(), &*FQ);
|
||||
|
||||
if a0 == Fq::new(am1).unwrap() {
|
||||
None
|
||||
} else {
|
||||
Some(a1a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn const_fq(i: [u64; 4]) -> Fq {
|
||||
Fq(U256::from(i))
|
||||
|
||||
+57
@@ -4,6 +4,7 @@ extern crate crunchy;
|
||||
extern crate rand;
|
||||
#[cfg(feature = "rustc-serialize")]
|
||||
extern crate rustc_serialize;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
|
||||
pub mod arith;
|
||||
mod fields;
|
||||
@@ -108,6 +109,19 @@ pub enum FieldError {
|
||||
NotMember,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CurveError {
|
||||
InvalidEncoding,
|
||||
NotMember,
|
||||
Field(FieldError),
|
||||
}
|
||||
|
||||
impl From<FieldError> for CurveError {
|
||||
fn from(fe: FieldError) -> Self {
|
||||
CurveError::Field(fe)
|
||||
}
|
||||
}
|
||||
|
||||
pub use groups::Error as GroupError;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
@@ -166,6 +180,10 @@ impl Fq {
|
||||
pub fn modulus() -> arith::U256 {
|
||||
fields::Fq::modulus()
|
||||
}
|
||||
|
||||
pub fn sqrt(&self) -> Option<Self> {
|
||||
self.0.sqrt().map(Fq)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Fq> for Fq {
|
||||
@@ -328,6 +346,24 @@ impl G1 {
|
||||
pub fn b() -> Fq {
|
||||
Fq(G1Params::coeff_b())
|
||||
}
|
||||
|
||||
pub fn from_compressed(bytes: &[u8]) -> Result<Self, CurveError> {
|
||||
if bytes.len() != 33 { return Err(CurveError::InvalidEncoding); }
|
||||
|
||||
let sign = bytes[0];
|
||||
let fq = Fq::from_slice(&bytes[1..])?;
|
||||
let x = fq;
|
||||
let y_squared = (fq * fq * fq) + Self::b();
|
||||
|
||||
let mut y = y_squared.sqrt().ok_or(CurveError::NotMember)?;
|
||||
|
||||
if sign == 2 && y.into_u256().get_bit(0).expect("bit 0 always exist; qed") { y = y.neg(); }
|
||||
else if sign == 3 && !y.into_u256().get_bit(0).expect("bit 0 always exist; qed") { y = y.neg(); }
|
||||
else if sign != 3 && sign != 2 {
|
||||
return Err(CurveError::InvalidEncoding);
|
||||
}
|
||||
AffineG1::new(x, y).map_err(|_| CurveError::NotMember).map(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
impl Group for G1 {
|
||||
@@ -580,3 +616,24 @@ impl From<AffineG2> for G2 {
|
||||
G2(affine.0.to_jacobian())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate rustc_hex as hex;
|
||||
|
||||
use super::{G1, Fq};
|
||||
|
||||
fn hex(s: &'static str) -> Vec<u8> {
|
||||
use self::hex::FromHex;
|
||||
s.from_hex().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g1_from_compressed() {
|
||||
let g1 = G1::from_compressed(&hex("0230644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46"))
|
||||
.expect("Invalid g1 decompress result");
|
||||
assert_eq!(g1.x(), Fq::from_str("21888242871839275222246405745257275088696311157297823662689037894645226208582").unwrap());
|
||||
assert_eq!(g1.y(), Fq::from_str("3969792565221544645472939191694882283483352126195956956354061729942568608776").unwrap());
|
||||
assert_eq!(g1.z(), Fq::one());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user